decentralized-identity / keri

Key Event Receipt Infrastructure - the spec and implementation of the KERI protocol
Apache License 2.0
73 stars 21 forks source link

Support for Ledger Registrar Backers #149

Open SmithSamuelM opened 3 years ago

SmithSamuelM commented 3 years ago

Currently the only Backer type supported by KERI are witnesses that participate in a witness pool using the KAACE distributed consensus algorithm. Witnesses are identified with an ephemeral (non-transferable) identifier that uses dedicated derivation codes for ephemeral non-transferable identifiers. Such coded identifiers include the public key is the identifier itself so no inception event or KEL is needed to verify signatures of a Witness. This is a performance optimization to avoid having to download KELs for witnesses and avoids the infinite regress of validating signatures of witnesses who have witnesses etc. When a witness' key is compromised, instead of rotating the witness keys, the witness identifier itself is rotated to a new ephemeral identifier. We rotate identifiers to rotate keys. The KEL events supports backer (witness) rotation by changing the set of identifiers.

However it has long been contemplated that KERI will support Backers that are registrars or oracles for shared ledgers such as Sovrin or Bitcoin etc. Currently there is not mechanism to distinguish between the Backer types and a ledger registrar backer does not participate in a KAACE consensus pool with witness backers.

The proposed mechanism here is that all non-witness backer types use non-ephemeral but non-transferable identifiers. A non-ephemeral but non-transferable identifier uses a transferable derivation code, thereby requiring an inception event but the nxt digest in its inception event is empty making it effectively non-transferable. But because an inception event is required we may use the seal list in the anchor field in the inception event to include a seal (digest) of all the configuration or meta data needed to know what ledger etc the Backer is tied too. This incepting meta-date can be provided as an attachment to the inception event for that Backer's identifier. Using a non-ephemeral but effectively non-transferrable identifier may avoid the infinite regress in that a Backer may not have backers (other than implicitly via the ledger itself that the backer is tied too).

This will require some code changes to detect non-witness Backers based on identifier type and inception event contents. This will be a different escrow path than witness backers. But the inception event allows us to securely designate any metadata needed to distinguish the Backer type and whatever else is needed to validate against that backer. Because the Backer identifier is still effectively non-transferable should the backer key-pair become compromised the Backer must be replaced with a new identifier. The same KEL event support for witness identifier rotation will work similarly for non-witness Backer identifier rotation.

pfeairheller commented 3 years ago

If I understand this correctly, the use case can be illustrated with the following example:

An Indy Ledger (Sovrin, for example) wants to provide Ledger Backer support for KERI identifiers with their ledger. So they would publish a non-ephemeral, non-transferable identifier inception event as a mechanism to publish the connection information needed to access their ledger. That connection information would be an attachment to the inception event with a digest of the attachment contents in a seal in the inception event.

I understand the desire to avoid the infinite regress. However, in the case of changing configuration information for the Ledger (adds/cuts of nodes, etc) wouldn't it be desirable to allow an event to commit to new configuration information without requiring everyone using this identifier as a witness to rotate to a new witness. Since the backer protocol will already change requiring the ingestion of an inception event for a Ledger Registrar backer, wouldn't it make sense to allow for other events for these identifiers to change the configuration information? This would also allow for key rotation if needed.

SmithSamuelM commented 3 years ago

I agree that There may be some rare use cases where one might want to have a TEL for the backer information or use a KEL for the backer keys itself and then use seals in that KEL. The proposal is meant to be the minimally sufficient means to support backers. We could allows variants that step up the security such as allowing multi-sig but still no rotation and then allowing rotation. However given that the original controller's KEL is the authoritative identifier for choosing backers. There is little if any reason from a security perspective to allow the backer to have rotatable keys. And a set of multiple backers provide a threshold structure that duplicates the security of multi-sig. A backer that is a registrar on a ledger also does not need more security because the events it registers on the ledger are protected by that ledger. Should the ledger access identifier of that backer be compromised then the controller may rotate to a new backer and effectively revoke the entries registered by the compromised backer register. But for highly valuable transactions on a ledger there might be a need for multi-sig of the backer as a rarity But rotatable multi-sig would be even rarer.

The KEL of the controller provides a mechanism to update metadata about each backer and that metadata may change by simply rotating the backer's identifier. Alternatively one could use TEL to provide backer metadata and then the metadata of the backer is pointed to by the metadata attached to the KEL event that declares the that Backer. But none of these mechanisms require the Backer have a rotatable/transferable identifier. Or have its own backers. The TEL could have its own backers.

Discovery of the backer's identifiers is provided by the Controller's KEL. So there is no need for those identifiers to have independent existence outside of the Controller's KEL.

We spend so much effort supporting KELs that is easy to forget that the only reason one needs a KEL is for identifiers that are persistent and that means persistent across contexts. The Value of a public persistent identifier is that it has a reputation and a brand that needs to transcend or persist indefinitely. Otherwise we more simply just use ephemeral or effectively ephemeral identifiers that only exist within a given limited in time and space context. A private persistent identifier also has persistent value as a reputable identifier but not brand.

So design of KERI identifier systems should always ask the question: does this identifier and its controlling key(s) need to persist outside of its immediate context? If not then we don't need an independent KEL or at least one that is transferable. IN the case of Backers their value is solely a function of the context provided by the controller of the KEL to which they are a backer. The controller may rotate backer identifiers, therefore a backer identifier is effectively ephemeral not persistent. Thus identifiers are specific to that local context. If their keys get compromised the controller just rotates the identifiers which also rotates the keys but without needed a KEL for each backer (other than the trivial one with only the inception event.). The same entity that controls the backer's key(s) could be the same backer entity across each rotation but the the identifer/key changes. No reason to independently maintain a transferable KEL for each backer.

Indeed that same backer entity could be a backer for multiple KELs but would use a different effectively ephemeral identifier for each KEL.

This approach also better manages privacy. For example if a KEL is meant to be private but wants backers for more security then the backer identifiers want to be private as well. If a KEL is meant to be public, then the backer identifiers only become public because they are disclosed by that KEL. Having a separate persistent KEL for each backer harder for that controller to manage that privacy.

To reiterate the 99% use case for KERI is that identifiers will be ephemeral, and if not ephemeral, i.e. persistent they will be privately persisting. It is only the 1% case where identifiers are public persistent. And when ephemeral the private vs. public should be a function of the privacy vs public of any persistent identifiers providing their context.

SmithSamuelM commented 3 years ago

Another way to think of this is that a single persistent identifier with its KEL provides a root-of-trust for an ecosystem of ephemeral or effectively ephemeral identifiers that all share that root-of-trust. Adding more complexity by adding other KELs other than trivial ones (i.e. inception only) is just unnecessary complexity that does not improve the fundamental security of that root-of-trust. There is only one source-of-truth and root control authority for the whole ecosystem. It is the controller of the private keys of the KEL of that one and only one persistent identifier. Is there something I am missing? Or that does not make sense. Its a new idea in identity to have "control authority" over a decentralized root-of-trust which control authority is also the singular source-of-truth. It took some time and thought to get there.

SmithSamuelM commented 3 years ago

@pfeairheller

wouldn't it be desirable to allow an event to commit to new configuration information without requiring everyone using this identifier as a witness to rotate to a new witness.

If we set up a TEL for configuration information then the signer on the configuration information could be the Backer's signature. This is essentially how the KERI-DHT works for the ip addresses of witnesses. The DHT stores the equivalent of an A record for each witness. The witness is responsible for signing and registering with the DHT (which is a type of TEL) a recored that links its witness identifier to its IP address.

My point is that should that witnesses signature every become compromised, there is no reason that the DHT should ever need to keep track of dedicated witness' KEL. There is no reason that the witness needs to rotate its keys to recover from that key compromise. The controller of the KEL for which that witness is a witness may simply rotate to a new witness identifier with new keys and that new witness identifier then registers its IP address (could be the same one) with the DHT. The DHT only accepts A records for a witness if that witness is a valid witness for some KEL in the DHT. So when a controller rotates out a witness it also effectively revokes the A record of that old witness in the DHT.

So in the case were we are not using ephemeral Backer identifiers like we are with witnesses but are using effectively non-transferable identifiers that have only an inception event (we need some new terminology). I think ephemeral non-transferable and non-ephemeral non-transferable might be better. Then that inception event is for all intents and purposes the TEL for that Backer. Its a one shot TEL.

So the real question is are there use cases where a backer would need to change its configuration without changing its identifier. Recall that the identifier when self addressing is strongly bound to the contents of its inception event. It is as secure as it will ever be. If we change its configuration then how is that change secured? We would need a TEL for that backer and a new event in the controller's KEL to anchor that TEL transaction that changed configuration. This would only make sense if the TEL anchors were in IXN interaction events, because if they were in a rotation event, then the controller could have more simply replaced the backer with a new one via the rotation instead of indirectly changing its configuration. But now we have a case where a verifier of that KEL can't depend on the configuration of a given backer they have to lookup in the TEL. This is more complex so should not be the default.

But I recognize that going forward there may be use cases where backer's non-essential non-key based configuration changes often enough that we don't want to be rotating a KEL in order to change a given backer's configuration.

But the use case we are taking about now is a Backer that is a Sovrin Registrar. The configuration for Sovrin is unlikely to change at all unless for example the access keys for the Backer to register events on the Sovrin ledger become compromised and in that case we are not simply changing non-essential Backer configuration but changing the Backer's access keys and rotation in the KEL is the secure way to protect such a key change, which is how we do it for witness keys. So for me the default should be backer configuration does not have a dedicated TEL unless it is something that is not key related like an IP address and then we let the DHT be that TEL.

We could also have a default TEL for each KEL that is for non-key related backer information that acts in lieu of a DHT for discovery. But we could just attach that information to an interaction event in the KEL that seals the attached information (this is how TrustFrame is planning to do it.) And extract it from the attachments by making the attachment counter type self describing.

The problem is discovery. How does a validator know that non-essential backer information has changed? A default TEL database for backer metadata would be one way to solve it. This is essentially a provenanced secure replacement for a DID:DOC. A DID:Doc is essentially a database record of any configuration information that one wants to discover about a DID. Unfortunately its insecure because there is no verifiable provenance log. So a TEL based databases a verifiable provenance log that is secure by default and is the correct way to maintain a database of configuration information (not a did:doc according to the current W3C spec).

This is a long winded analysis. But the question is a good one because there are multiple ways to answer it. I am trying to delineate the options and trade-offs.

In summary:

Ledger Registrar Backers: The vital configuration is their access identifier on the ledger (bitcoin address). This is functionally a type of ephemeral identifier (no provenance log for rotations). It is not a KERI ephemeral identifier because it does not use the KERI syntax for derivation codes and format. But functionally it is ephemeral. So it has the same security posture as a KERI witness. Once that registrar creates a transaction on the ledger then that transaction is protected by the ledger. So no need for a watcher network (the ledger is both a witness and watcher network unto itself). Changing the ledger is not possible without creating a new access identifier (ethereum address for example) with new private key. This is a type of key rotation and so we want to protect that by rotating the Backer to a new Backer. For example, from a bitcoin backer to an ethereum backer. The most secure way to do that is to do a KEL rotation.

When I first worked through the KERI events, I finalized on only allowing witness changes with a rotation (establishment) event , not an interaction (non-establishment) event. The reason is that I could easily come up with exploits where compromised signing keys could change the security posture of a recovery rotation event by first changing the witness set to one the attacker controlled and then when the controller attempted to recover via a rotation the recovery was not protected by witnesses the controller controlled anymore. We would have the same issue with non-witness backers. TrustFrame originally had a related problem for NFTs that i pointed out because they did not make a commitment to restrict the backer set in their provenance log.

The policy for KERI is that if a Backer's keys change then that change requires a Rotation in the backed KEL. But if the Backer's identifier is a self-addressing identifier derived from the public keys (either in the inception event or as an ephemeral non-transferable identifier) then its identifier would also change anyway. So this would create a new backer identifier not a change in configuration of some backer with the same identifier.

Now if all I want to do is change the IP address of the Backer then that is a discovery problem and the keri-dht already solves that. But in lieu of a KERI dht, each KEL could have a default TEL that provides other non-key based "backer config" including witness backer config not merely ledger registrar backer config such as IP addresses. This TEL becomes a secure replacement for a did:doc and the did method for KERI could be extended to provide this default config TEL state in the did:doc.

Alternatively

There is no explicit TEL for backer configuration metadata. All the TEL data is attached to the event that anchors it in the original KEL and when a validator replays a KEL it extracts the attachments and store them locally. The validator then decides how to index that configuration data. No dedicated TEL needed because each validator just saves it in a table that is indexed by the backer identified in the attachment. Its a virtual TEL not an actual TEL. Unlike VCs backers are intimately tied to the KEL for which they back.

I like the this approach because it just a policy of how to index and discover backer configuration data that does not require any new infra-structure other than a new database table associated with the KEL that a given backer is backing. This new table holds the backer config state and is indexed by the backer's identifier. We could use a KOM for that. Or the table could be a log it just doesn't need to have independent existence. Its a virtual TEL. We would need a complex attachment type for each backer type of config data. But right now we only have two backer types. Witnesses and Ledger Registrars. I doubt there will be any others for quite some time.

Additionally when anchored (sealed) metadata is attached to the anchoring KEL then that data does not need to be signed. The seal is signed so the controller of the KEL is making a signed non-repudiable cryptographic commitment to that data. The fact that the data is associated with a backer who has its own key pair does not change the security posture of that anchored data. Moreover its more secure than allowing the backer to make independant but not anchored commitments to configuration data that is merely signed by the backer. The controller then has no way of monitoring what the backer is doing unless the backer creates TEL and publishes it to the controller. The controller now has the burden of monitoring what the backer is doing to discover if the backer has been compromised.
We really do not want to create extra burden on controllers to monitor backer behavior. In the case of witnesses the only thing a witness can do is create receipts that are attached to the KEL. By virtue of their attachment the controller is able to monitor without additional burden the behavior of a witness. So if we restrict the behavior of a backer to only signing data that has been anchored first by the controller and then attached to an event then the controller only has to monitor one thing, its own KEL.

This actually makes me thing that I need to change how KERI-DHT-PY works. I should require that when a witness needs to change its IP address, the controller anchors that new IP address in its KEL with a seal in one of its events. Then the witness publishes that new IP address to the DHT and includes an event seal in that publication. The DHT can then verify that the new IP address is valid. Any validator can do the same. The witness stills signs that publication as a spam DDoS protection but now the controller doesn't care about monitoring the IP addresses of its witnesses that have been published to the DHT. The DHT won't update a witness A record without first validating that the update has been anchored in the KEL.

We can repurpose the receipt message to also mean: Here is a disjoint attachment of any kind for the event referenced in the receipt message body.
In that sense a receipt could be thought of as a disjoint attachment message. Sometimes the attachments are signatures and other times the attachments are anchored metadata.

OK this is good. We now have a general policy that makes the controller KEL able to better monitor and therefore control the behavior of its Backers. Backers sign things for DDoS protection but configuration data is all anchored so the authoritative signature is the controller's is on the anchor not backer's on the metadata. This is way more secure.

SmithSamuelM commented 3 years ago

To summarize again.

The policy is that Backers can only endorse something previously committed to via a seal in the KEL for which the backer is a backer.

This brings full circle the meaning of endorse. (BTW endorser is not a word in the dictionary, only the verb endorse is).

Backers may only endorse a prior commitment made by the controller. This means that a validator may drop any signed statement by a backer that has not already been anchored on the KEL.

This applies to a witnesses in a witness pool are a single ledger registrar. IN the case of a witness pool the independent keys of each witness provide security via a threshold structure. In the case of a ledger registrar the ledger access keys of the registrar enable it to cross anchor the controller's commitment in its KEL on a ledger. This provides duplicity protection via the ledger instead of a watcher network. The first registration on the Ledger wins because ledgers are totally ordering. If a ledger registrar's access key(s) become compromised then the controller rotates to a new registrar with new key(s). A validator then may ignore any new entries made by that old registrar after it has been rotated out because they won't have corresponding prior commitments in the KEL. Only the new registrar will.

The registrar's KERI identifier is derived from an inception event where the public key is a KERI formatted version of that registrars access public key. This binding tightly the access identifier on the ledger to the Keri identifier used to designated that registrar as a backer.

For example bitcoin: Bitcoin address is a fingerprint of a EcDSA_secp_256_k1 public key. We put that public key in the inception event for that backer registrar and derive the resultant KERI identifier. So all the KERI attachments etc use that identifier but any validator can derive the bitcoin corresponding bitcoin address and confirm which transactions on the bitcoin ledger come from the bitcoin version of that same public key.

For example Sovrin: Sovrin Nym is a fingerprint of a Ed25519 public key. We put that public key in the inception event and the rest is that same as above.

pfeairheller commented 3 years ago

Now if all I want to do is change the IP address of the Backer then that is a discovery problem and the keri-dht already solves that. But in lieu of a KERI dht, each KEL could have a default TEL that provides other non-key based "backer config" including witness backer config not merely ledger registrar backer config such as IP addresses. This TEL becomes a secure replacement for a did:doc and the did method for KERI could be extended to provide this default config TEL state in the did:doc.

This is the essence of what I was asking and describes a solution approach pretty well...

But this:

The witness stills signs that publication as a spam DDoS protection but now the controller doesn't care about monitoring the IP addresses of its witnesses that have been published to the DHT. The DHT won't update a witness A record without first validating that the update has been anchored in the KEL.

And this:

There is no explicit TEL for backer configuration metadata. All the TEL data is attached to the event that anchors it in the original KEL and when a validator replays a KEL it extracts the attachments and store them locally.

Describe the solution that I think you just summarized. Changing the DHT to help address this is a win, in my opinion.

SmithSamuelM commented 3 years ago

Yes I just had to reason through all the options to get clarity in my own mind.

We don't need an explicitly identified default TEL with unique message types for backer config. We just need explicitly defined attachment types for baker config. The default TEL is the KEL with those attachments stored in a new table. The message type for sending disjoint backer config attachments is just the existing rct message. We add a table to the database indexed or keyed by Tuple (controller prefix, backer prefix) with value being the backer config data. If we want to provenance it then we prepend to the data a sequence number or insertion order number and store all dups versions in order of the event to which they are anchored.

We can add a query message to request config data for a backer from a remote KEL host. But if we have a local copy of the KEL then we don't need a message to get it.

Stand-alone TELs are needed for data like VCs that have issuance and revocation or other state that is not so closely tied to a given KEL. Whereas backer config is much more closely tied. Also VCs need horizontal scalability for managing their state. Backers do not, should not. A standalone TEL enables horizontal scalability and may use different infra-structure from its associated KEL. We don't need or should not need those features for backer config.