# Aries RFC 0000: Group DID Exchange Protocol 1.0 - Authors: [Mikhail Lytaev](mikelytaev@gmail.com) - Status: [PROPOSED](https://github.com/hyperledger/aries-rfcs/blob/main/README.md#proposed) - Since: 2022-07-15 - Status Note: - Supersedes: - Start Date: 2022-07-15 - Tags: [feature](https://github.com/hyperledger/aries-rfcs/blob/main/tags.md#feature), [protocol](https://github.com/hyperledger/aries-rfcs/blob/main/tags.md#protocol) ## Summary Настоящий RFC определяет протокол создания и управления отношениями внутри группы [агентов](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0004-agents) (nwise). В определенном смысле является обощением понятия pairwise и протоколов [0160](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol) и [0023](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange) на произвольное число агентов. ## Motivation Субъекты SSI и представляющие их агенты должны иметь способ установки взаимоотношений друг с другом. В простейшем случае, когда участвуют два агента, эта цель достигается при помощи протокола [RFC 0023 DID Exchange](https://github.com/hyperledger/aries-rfcs/blob/main/features/0023-did-exchange/README.md) путем создания и защищенного обмена своих DID Documents непосредственно между агентами. Однако часто возникает необходимость организовать взаимодействие, в котором участвуют более двух агентов. При этом число участников может меняться с течением времени, а большая часть агентов может быть мобильными. Наиболее простой и часто используемый пример такого взаимодействия - групповые чаты в instant messager. Доверенная природа технологии SSI позволяет использовать nwise для проведения юридически значимых собраний, например собраний собственников жилья или заседаний диссертационных советов. ## Tutorial ### Реестр состояний NWise Текущее состояние n-wise представляет собой актуальный список DID Documents участников. В случае с pairwise состояние хранится у участников и обновляются при необходимости непосредственным оповещением другой стороны. Когда участников больше 2 - возникает проблема синхронизации состояния этого n-wise - т.е. консенсуса. При этом нужно учитывать, что состояние может периодически меняться: пользователи могут добавляться или удаляться, могут изменяться их DID Document (при ротации ключей или изменении Endpoint). Можно выделить следующие варианты хранения состояния участников: - #### Непосредственно у участников Этот подход наиболее близок к [RFC 0023 DID Exchange](https://github.com/hyperledger/aries-rfcs/blob/main/features/0023-did-exchange/README.md), однако т.к. участников больше 2х - требуется процедура консенсуса для корректного учета изменений в состоянии nwise. Даныый вариант подходит, если участники - облачные агенты, которые (почти) всегда онлайн. В этом случае между ними можно уставовить консенсус известными алгоритмами (RAFT, Paxos, BFT). Однако если большинтство агентов мобильные и находятся в сети лишь эпизодически, известные алгоритмы консенсуса перестают работать. Так что для хранения и обновления состояний нужно некоторое внешнее хранилище. - #### Публичном или приватном распределенном реестре (DLT) В этом случае задачу записи и хранения состояния берет на себя стороняя распределенная сеть. Сеть может валидировать приходящие в нее транзакции путем исполнения смарт контракта, либо принимать все входящие транзакции (в этом случае валидация транзакций происходит на стороне агентов-участников). - #### Централизованном хранилище Если требования безопасности позволяют участникам доверять централизованному решению, то хранение транзакций можно осущестлять централизованно. Изменения состояния NWise осуществляется путем записи соответствующей транзакции в реестр состояний. Для получения актуального состояния n-wise агент получает список транзакций, верифицирует их и применяет по очереди согласно установленным ниже правилам, начиная с `genesisTx`. Некорректные транзакции (без надлежащей подписи или несодержащие необходимых полей) игнорируются. Особенности записи и получения транзакций зависят от выбранного способа ведения реестра состояний и от конкретного DLT. Данный RFC НЕ ОПРЕДЕЛЯЕТ конкретные реализации хранилища состояний. ### Роли #### Участник Субьект, принимающий участие в nwise. ##### Пользователь Имеет право вносить изменения в свой DID Document и удалять себя из nwise. ##### Администратор В дополнение к правам пользователя, имеет право добавлять и удалять пользователей, вносить изменения в метаинформацию и nwise, изменять роль пользователя. #### Создатель Автор `genesisTx`. Автоматически назначается администратором. #### Inviter Участник (в роли администратора), который инициирует приглашение нового агента. #### Invitee Агент, осуществляющий принимающий приглашение и подключающийся к nwise. ### Создание NWise Создатель должен создать реестр состояний. Создание NWise заключается в записи `genesisTx` в реестр состояний. Создатель автоматически считается администратором nwise. Создатель ДОЛЖЕН сгенерировать новый уникальный did и DID Document для NWise. ### Приглашение участника Любой участник с ролью администратора может создать приглашение на присоединение к NWise. Сначала Inviter генерирует пару публичного и приватного ключа приглашения согласно Ed25519. Публичный ключ приглашения записывается в реестр в транзакции типа `invitationTx`. Пара ключей приглашения является уникальной для каждого Invitee и может быть использована только один раз. Затем приватный ключ приглашения высылается Invitee по независимому каналу в виде сообщения `Invitation` ### Принятие приглашения Получив `Invitation`, Invitee генерирует новуй уникальный DID и DID Document для данного NWise и добавляет транзакцию `AddParticipantTx` в реестр. Процесс добавления нового участника показан на рисунке ниже ![](https://i.imgur.com/1oji1Rv.png) ### Обновление DID Document Обновить DID Document может только сам пользователь. Соответствующая транзакция должна быть подписана ключем, определенным в предыдущем DID Document. ### Удаление пользователя Пользователь может удалить сам себя (в этом случае соответствующая транзакция подписывается публичным ключем пользователя). Пользователя так же может удалить администратор (в этом случае соответствующая транзакция подписывается публичным ключем администратора). ### Обновление метаинформации об NWise Метаинформация может быть обновлена только администратором (соответствующая транзакция позписывается ключом администратора) ### Нотификация об изменении в реестре состояний Сразу после добавления очередной транзакции в реестр состояний, участник ДОЛЖЕН отправить всем остальным участникам сообщение `LedgerUpdateNotify`. Участник, получивший `LedgerUpdateNotify` ДОЛЖЕН получить актуальное состояние из реестра состояний. Пренадлежность полученного сообщения к определенному nwise определяется по verkey отправителя. ## Reference ### Транзакции состояния NWise Состояние NWise меняется при помощи транзакций. ```json { "type": "transaction type", ... "proof" { "type": "JcsEd25519Signature2020", "verificationMethod": "did:alice#key1", "signatureValue": "..." } } ``` #### Attributes `type` обязятельный атрибут, указывающий тип транзакции `proof` обязательный атрибут  [JSON-LD Proof](https://w3c-ccg.github.io/data-integrity-spec/). `verificationMethod` зависит от конктетного типа транзакции и будет определен далее ### GenesisTx ```json { "type": "genesisTx", "label": "Council", "creatorNickName": "Alice", "creatorDid": "did:alice", "creatorDidDoc": { .. }, "ledgerType": "iota@1.0", "metaInfo" { ... } } ``` #### Attributes `label` обязательный атрибут - название nwise `creatorNickname` обязательный атрибут - ник создателя `creatorDid` обязательный атрибут - DID создателя `creatorDidDoc` обязательный атрибут - DID Document создателя `ledgerType` обязательный атрибут - тип используемого реестра состояний `metaInfo` необязательный атрибут - дополительная метаинформация об nwise, формат которой определяется контретной реализацией реестра состояний Транзакция `genesisTx` должна быть подписана ключем создателя, определенном в его DID Document. ### InvitationTx ```json { "type": "invitationTx", "publicKey": [ { "id": "invitationVerkeyForBob", "type": "Ed25519VerificationKey2018", "publicKeyBase58": "arekhj893yh3489qh" } ] } ``` #### Attributes `publicKey` обязательный атрибут - массив публичных ключей приглашения `id` обязательный атрибут - идентификатор публичного ключа приглашения `type` обязательный атрибут - тип публичного ключа приглашения `publicKeyBase58` обязательный атрибут - публиный ключ приглашения в формате Base58. ### Invitation message ```json { "@id": "5678876542345", "@type": "https://didcomm.org/n-wise/1.0/invitation", "label": "Invitaion to join nwise", "invitationKeyId": "invitationVerkeyForBob", "invitationPrivateKeyBase58": "qAue25rghuFRhrue....", "ledgerType": "iota@1.0", "ledger~attach": [ { "@id": "attachment id", "mime-type": "application/json", "data": { "base64": "<bytes for base64>" } } ] } ``` #### Attributes `label` необязательное поле, предсавляющее собой человекочитаемый текст `invitationKeyId` идентификатор ключа приглашения `invitationPrivateKeyBase58` приватный ключ приглашения `ledgerType` тип используемого реестра состояния nwise `ledger~attach` вложение, содержащие необходимую для подключения к реестру метаинформацию. Определяется в зависимости от выбранного реестра. ### AddParticipantTx ```json { "id": "addParticipantTx", "nickname": "Bob", "role": "user", "did": "did:bob", "didDoc": { ... } } ``` #### Attributes `nickname` обязательное поле - ник пользователя `did` обязательное поле - DID пользователя `didDoc` обязательное поле - DID Document пользователя Транзакция `AddParticipantTx` ДОЛЖНА быть подписана приватным ключем `invitationPrivateKeyBase58`, полученным в `Invitation`. После добавления транзакции `AddParticipantTx` пара ключей приглашения, которой указанная транзакция была подписана, считается деактивированной (другие приглашения ей подписаны быть не могут). Исполнитель транзакции ДОЛЖЕН проверить, что ключ преглашения действительно был ранее добавлен. Исполнение транзакции влечет добавление нового участника. ### UpdateParticipantTx ```json { "type": "updateParticipantTx", "did": "did:bob", "nickname": "Updated Bob", "didDoc" { ... } } ``` #### Attributes `did` обязательный атрибут - DID пользователя, информация о котором обновляется `nickname` необязательный атрибут - новый ник пользователя `didDoc` необязательный атрибут - новый DID Document ### RemoveParticipantTx ```json { "type": "removeParticipantTx", "did": "did:bob" } ``` #### Attributes `did` обязательный атрибут - DID удаляемого пользователя Исполнение транзакции влечет удаление пользователя и его DID Document из списка участников. ### UpdateMetadataTx ```json { "type": "updateMetadataTx", "label": "Updated Council" "metaInfo": { ... } } ``` #### Attributes `label` необязательный атрибут - новое название nwise `metaInfo` необязательный атрибут - новая метаинформация ### LedgerUpdateNotify ```json { "@id": "4287428424", "@type": "https://didcomm.org/n-wise/1.0/ledgerUpdateNotify" } ``` ## Drawbacks Необходимость в публичном DLT ## Rationale and alternatives Публичные DID используют ту или иную блокчейн сеть для хранения своего DID Document. [Peer DID](https://identity.foundation/peer-did-method-spec/) отвергает использование блокчейна для хранения состояния DID, что абсолютно логично для pairwise отношений, т.к. DID Document может храниться у партнера. По мере роста числа участников взаимоотношения актуализируется задача консенсуса состояния. В определенном смысле n-wise является чем-то среденим между peer DID (когда DID Document хранится только у партнера) и публичным DID, когда DID Document должен быть доступен неограниченному кругу лиц. Для этого в данном RFC было формально введено понятие реестра состояний, а его конкретные реализации (консенсус между участниками или сторонний доверенный реестр) отсаются на усмотрение создателя n-wise. Данный RFC НЕ ОПРЕДЕЛЯЕТ способ обмена сообщениями внутри группы. В простейшем случае это может быть реализовано как отправка сообщения поочередно каждому участнику. В некоторых случаях целесообразно рассмотреть возможность использования централизованного координатора, который бы отвечал за упорядочивание и гарантированную отправку сообщений от отправителя отсатьным участникам. Интерестной высокоуровненой концепцией построения n-wise протоколов является [Gossyp](https://github.com/dhh1128/didcomm.org/tree/gossyp/gossyp). ## Prior art Понятие n-wise было предложено в спецификации метода [Peer DID](https://identity.foundation/peer-did-method-spec/), а ранее концептуально обсуждалось в [документе](https://docs.google.com/document/d/1BjYdivGQ9GxIz9CJ2ymNvMA68uHZm8bFOTyCHDmziOU/edit#). Однако строгой формализации данного процесса предложено не было. ## Unresolved questions Это протокол? или feature? или concept? Кто должен отвечать за порядок транзакций? Где определять конкретные реализации реестра состояний (отдельные rfc?) Напрашивается понятие microledger Нужна ли возможность замены реестра? Возможно, иерархию пользователей тоже стоит сделать pluggable? ## Implementations The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. Name / Link | Implementation Notes --- | --- [Sirius SDK Java](https://github.com/Sirius-social/sirius-sdk-java/) | [IOTA Ledger](https://www.iota.org/) based implementation