Skip to content
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

refactor(rust): extract identity as an entity #4542

Merged
merged 9 commits into from Apr 18, 2023

Conversation

etorreborre
Copy link
Member

@etorreborre etorreborre commented Mar 24, 2023

Introduction

This PR aims at simplifying the current handling of identities to provide:

  • a better notion of Identity: at the moment an Identity is not only a set of key changes representing a specific actor in the system but also a set of services shared by all the actors (to persist keys, sign them, store attributes etc...). As a result a redundant notion of PublicIdentity had to be introduced. Moreover it is not even possible to simply clone an Identity since it contains a Context

  • a more consistent and navigable API for the available services which can be used to

    • create / import identities
    • store attributes / issue credentials
    • create secure channels

Since the notion of Identity is tied to most of the library, this PR is necessarily touching many files. The following sections describe the main changes:

The ockam_identity crate

The top-level folders in the ockam_identity crate are organized around "entity" (singular) and "entities" (plural, services for 'entity') modules:

  • credential: CredentialData, Credential
  • credentials: Credentials service
  • identity: Identity, IdentityChangeHistory, IdentityIdentifier
  • identities: Identities, IdentitiesCreation services
  • secure_channel: TrustOptions, Addresses etc...
  • secure_channels: SecureChannels services

Data types

The main changes are:

  • Identity is now just a set of key changes and an identifier, no more services, no more Context
  • PublicIdentity (and corresponding functions) has been removed
  • CredentialBuilder had to have some modifications to incorporate the issuer (it was implicit before when doing identity.issue_credential)

Node Services

Identities is a set of services to manage identities

  • IdentitiesCreation to create / import identities
  • IdentitiesKeys to manage identities keys
  • Credentials to manage attributes and credentials
  • CredentialsServer to start a worker serving credentials

The Identities services are backed up by

  • an IdentitiesVault to store keys and provide cryptographic information
  • an IdentitiesRepository to persist identities data (attributes etc...). It has 4 interfaces
    • IdentityAttributesWriter to persist the attributes of an identity
    • IdentityAttributesReader to retrieve the attributes of an identity
    • IdentitiesWriter to persist a known identity
    • IdentitiesReader to get a persisted known identity

SecureChannels is a set of services used to create secure channels

  • it uses Identities services (so it uses the same underlying vault)
  • it has a SecureChannelsRegistry

Note on vaults: strictly speaking there is one less vault interface needed to manage identities (no need for SymmetricVault). However introducing a distinction between IdentitiesVault and SecureChannelsVault led to more difficulties than necessary for no obvious modularity gain.

Additional note the Context which was stored before inside Identity is now explicitly passed as an argument when running operations requiring it, for example to create a secure channel. This makes that part slightly more verbose but now it also dispense of the creation of a full Context when doing simple identity operations like storing attributes.

Builders

Identities and SecureChannels can be created using a builder pattern. For example

let identities = identities::builder().with_identities_storage(FileStorage::new("identities")).build()

In the user guide examples a Services struct is available, and gives access to all the required services to create identities, secure channel, access credentials etc... (see the modified examples). This leaves the room open for other types of services (projects, spaces?). It also opens the possibility to encapsulate the creation of transports in the future (services.create_tcp_transport().await?) but I haven't explored that yet.

The ockam_api crate

NodeManager

The NodeManager now has

  • an Identity
  • an optional credential
  • SecureChannels services (all sub-services like identities_creation can be directly accessed via NodeManager::self

The independent Vault and AttributesStorage have been removed since they are now implementation details of SecureChannels. The NodeManager uses a SecureChannels builder.

NodeIdentities

A NodeIdentities struct has been introduced to help implement the IdentitiesService endpoint, where a default vault is used unless a vault name is specified. I suspect that there could be better/more refactorings there.

The ockam_command crate

On the ockam_command side we are mostly adapting to the changes in ockam_api. One thing to notice is that it is less frequent to require a Context to run operations.

Examples

At the top-level, since we separate an Identity from various capabilities (creation, secure channels), we need to change the user-facing API. The proposal is to do the following:

// Create an Identity to represent Alice.
let node = node(&ctx);
let alice = node.create_identity().await?;
...
// Connect to a secure channel listener and perform a handshake.
let r = route![connection_to_middle_node, "forward_to_bob", "bob_listener"];
let channel = node
      .create_secure_channel(&alice, r, TrustEveryonePolicy).await?;

In the code above:

  • we instantiate a default set of ockam services as a node. The default implementations of all services is storing data in-memory but there is also a node::builder() to configure exactly how we want implementations to behave

  • we obtain various capabilities: create identities, or start secure channels from the services variable. One advantage of this approach is that it makes the top level api discoverable in and IDE by simply asking the IDE to propose completions

TO BE DONE

The CHANGELOG files for each crate have not been updated with all the changes yet.
Examples in the documentation also need to be updated.

@etorreborre etorreborre force-pushed the etorreborre/refactor/identity-as-entity-2 branch 12 times, most recently from 5526ae7 to 523f435 Compare March 30, 2023 10:41
@etorreborre etorreborre self-assigned this Mar 30, 2023
@etorreborre etorreborre force-pushed the etorreborre/refactor/identity-as-entity-2 branch 15 times, most recently from 959ab00 to b37447d Compare March 30, 2023 21:36
@etorreborre etorreborre marked this pull request as ready for review March 30, 2023 21:56
@etorreborre etorreborre requested a review from a team as a code owner March 30, 2023 21:56
@etorreborre
Copy link
Member Author

@mrinalwadhwa we can plug-in vaults and transports with this PR. You also wrote "async executor". How is it possible at the moment since the node macro gives you a Context fully wired to an executor? This is done via the compilation configuration, right?

SanjoDeundiak
SanjoDeundiak previously approved these changes Apr 17, 2023
Copy link
Member

@SanjoDeundiak SanjoDeundiak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't go through the whole PR due to its size, but the structure overall looks good to me. We can merge and discuss later

@etorreborre etorreborre force-pushed the etorreborre/refactor/identity-as-entity-2 branch 7 times, most recently from 077a7f6 to ba573f5 Compare April 18, 2023 10:10
@etorreborre etorreborre force-pushed the etorreborre/refactor/identity-as-entity-2 branch from ba573f5 to 4e8a295 Compare April 18, 2023 10:33
to be able to compile rust doc examples to build a node
@etorreborre etorreborre force-pushed the etorreborre/refactor/identity-as-entity-2 branch from 60e5556 to d323cea Compare April 18, 2023 12:31
@etorreborre etorreborre added this pull request to the merge queue Apr 18, 2023
Merged via the queue into develop with commit 7f21117 Apr 18, 2023
77 checks passed
@etorreborre etorreborre deleted the etorreborre/refactor/identity-as-entity-2 branch April 18, 2023 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants