-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: remove keys on mediator when deleting connections #1143
feat: remove keys on mediator when deleting connections #1143
Conversation
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Codecov Report
@@ Coverage Diff @@
## main #1143 +/- ##
==========================================
+ Coverage 88.34% 88.48% +0.14%
==========================================
Files 706 706
Lines 16436 16468 +32
Branches 2662 2670 +8
==========================================
+ Hits 14520 14572 +52
+ Misses 1909 1889 -20
Partials 7 7
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
Signed-off-by: Ariel Gentile <[email protected]>
const connection = await this.connectionService.getById(this.agentContext, connectionId) | ||
|
||
if (connection.mediatorId && connection.did) { | ||
const did = await this.didResolverService.resolve(this.agentContext, connection.did) | ||
|
||
if (did.didDocument) { | ||
await this.routingService.removeRouting(this.agentContext, { | ||
recipientKeys: did.didDocument.recipientKeys, | ||
mediatorId: connection.mediatorId, | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thinking forward a bit here. If we start supporting public dids I could have multiple connections using the same did, thus removing all the keys at the mediator could lead to issues for other connections. That's not the case at the moment, but just thinking here whether that could lead to issues in the future.
Also we have the didRecord that contains the recipientKeys of the did document, which means we wouldn't have to fetch it from the ledger. Not sure though if that's a better approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point here. So the goal is to simply remove the recipientKeys needed for this particular connection, provided they won't affect other connections also related to the same public DID.
If i'm not wrong, even if we are using public DIDs for invitations, we will be always doing some sort of key rotation, because otherwise we wouldn't know, when receiving a message, which connection is that message for. What would be the most direct approach to get the actual recipient keys I need to delete?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would be the most direct approach to get the actual recipient keys I need to delete?
Note sure. That can be really difficult. We would need to check whether any connection of our of band invitation exist with a did that uses a specific key.... I think for now this is fine. We will probably keep the behaviour as you described until at least didcomm v2 and then we only work with dids rather than keys, so it will be easier to discover I guess.
We also don't delete keys for connectionless exchanges after they're done (can be hard to determine what done means in a generic way). We should probably also add that
@@ -565,6 +564,20 @@ export class OutOfBandApi { | |||
* @param outOfBandId the out of band record id | |||
*/ | |||
public async deleteById(outOfBandId: string) { | |||
const outOfBandRecord = await this.getById(outOfBandId) | |||
|
|||
const relatedConnections = await this.connectionsApi.findAllByOutOfBandId(outOfBandId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can become quite an expensive query if you have a lot of connections created. Another reason to support pagination...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes... Hopefully, delete operations will not be so common, so the performance impact would not be so big.
const relatedConnections = await this.connectionsApi.findAllByOutOfBandId(outOfBandId) | ||
|
||
// If it uses mediation and there are no related connections, proceed to delete keys from mediator | ||
if (outOfBandRecord.mediatorId && (relatedConnections.length === 0 || outOfBandRecord.reusable)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we delete the recipientKeys if the oob record is reusable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an Out of Band record is reusable, every time a new connection is created based on it, a new recipient key will be created and shared with the mediator. My reasoning is that if we delete the out of band record we will not be affecting any connection created from it, and therefore we are safe to delete that key on mediator. Maybe I'm missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that makes sense, hadn't thought about it. Maybe add it as a comment to the code :)
@@ -370,8 +373,22 @@ export class RecipientApi { | |||
return mediationRecord | |||
} | |||
|
|||
public async notifyKeylistUpdate(connection: ConnectionRecord, verkey: string) { | |||
const message = this.mediationRecipientService.createKeylistUpdateMessage(verkey) | |||
public async notifyKeylistUpdate(connection: ConnectionRecord, verkey: string, action?: KeylistUpdateAction) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really related to this PR, but maybe we can update this method to something like:
public async notifyKeylistUpdate(connection: ConnectionRecord, verkey: string, action?: KeylistUpdateAction) { | |
public async notifyKeylistUpdate({ | |
connectionId: string | |
publicKeyBase58: string // or even publicKeyFingerprint | |
action: KeylistUpdateAction // make action required | |
}) { | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. I just didn't want to introduce breaking changes at the API level on this PR. But for sure this method must be updated. I would like to do something similar to Discover Features module, where we have the option of doing sync or async queries, in order to have a more harmonized Recipient API
endpoints: mediationRecord.endpoint ? [mediationRecord.endpoint] : routing.endpoints, | ||
routingKeys: mediationRecord.routingKeys.map((key) => Key.fromPublicKeyBase58(key, KeyType.Ed25519)), | ||
} | ||
} | ||
|
||
public async removeMediationRouting( | ||
agentContext: AgentContext, | ||
{ recipientKeys, mediatorId }: RemoveRoutingOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the service level we usually use records over ids, not sure if using a record is better here though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. It was just to have a similar API to addMediationRouting
, which also takes mediatorId. Overall I think the API used in this module is quite different from other parts of the framework.
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
Signed-off-by: Ariel Gentile <[email protected]>
This PR addresses the case where a mobile agent (or any agent that uses mediator) deletes a connection or OOB record, meaning that the corresponding recipient keys should be removed from its mediator (as per Aries RFC 0211). Otherwise, mediator will still be forwarding messages to the agent that can't (and more importantly don't want to) be handled.
This will mean that, when using mediator, in order to delete a connection or out-of-band record, the agent must be online. This is aligned to the opposite case: connection and OOB invitation creation, which also need the agent to be online to be in sync with its mediator.