Remove certificates from confidential identities



The end goal here is to decouple the signing keys from the node’s identity. This will be accomplished by removing the use of certificates in confidential identities and cleaning up PersistentIdentityService

Current Functionality

The current CI has a few issues:

  • Serialization and storage of the certificate chain for each new key that is registered.

  • SwapIdentitiesFlow doesn’t make much sense since it’s usually only one party that requests a new key.

The PersistentIdentityService has a few inefficiencies that we will address during this refactor. It currently has two AppendOnlyPersistentMaps:

  • keyToParties = Map<PublicKey, PartyAndCertificate>

    • Updated every time we register a new party (confidential or otherwise)

  • principalToParties = Map<CordaX500Name, PublicKey>

    • This map is only used in conjunction with the keyToParties map to find a well known party from a public key. It is currently updated every time we register any new identity. Hogwash.

Proposed Functionality

API Changes

Add an additional API to IdentityServiceInternal

This will allow us to store a PublicKey to a Party without requiring the cert chain. We can then use IdentityService.wellKnownPartyFromAnonymous to look up the Party object.

Identity service

1. Retain principalToParties and only update when a new node is added to the network map cache. We need this table to perform the partiesFromName lookup for the interactive shell. New CIs should not be added to this table.

2. Retain keysToParties. We need this to serve the methods which return PartyAndCertificate s. It should only be updated when a new party is added to the network map cache. It doesn't need to be updated with confidential identities. We’re bounded by backwards compatibility because of IdentityService.certificateFromKey(owningKey: PublicKey): PartyAndCertificate? or we could’ve stripped certificates out entirely.

3. Add a new table which is keyToPartyMapping that should contain all public keys mapped to their respective Party objects. This means all legal identity keys as well as confidential identity keys will be in this map.

4. We need to perform a migration at new version startup to move all the entries in the keysToParties table to the new table: keyToPartyMapping. This only needs to be done once.


The new signed data structure that will be used within the flows is as follows:

We will introduce three new flows:

  • RequestKeyFlow (in-line)

    • A party can request a new key to be generated by the handler, assigned to an external ID. The handler creates the SignedPublicKey with a mapping of the new key to the host nodes Party.

    • The initiating flow verifies the signature, and then calls our new IdentityService.registerIdentityMapping method.

  • ShareKeyFlow (in-line)

    • The host node generates a new key pair and sends the mapping to the handler. The handler verifies the signature and then registers the new identity mapping.

  • SyncKeyMappingFlow (in-line)

    • Mirrors the functionality of the existing IdentitySyncFlow whereby we ensure that our counter-parties in a transaction have the mappings for our confidential identities used in states present in the transaction.


Will Hester


Will Hester




Epic Link




Engineering Teams


Fix versions

Affects versions


Ported to...

Corda 4.3

Story Points / Dev Days


Build cut