...
Subscriptions allow two picos to communicate with each other on a secure channel. Subscriptions have several advantages characteristics and uses:
- Subscriptions can occur between any two picos, augmenting the parent-child hierarchy to create peer-to-peer structures.
- Subscriptions allow picos to establish communication channels with relationships.
...
- .
From each pico's perspective there is an receiving channel , Rx , and an transmitting channel, Tx. The pico receives events and queries from the other pico in the subscriptions over the Rx channel and makes queries and sends events to the other pico using the Tx channel.
Subscriptions can exist between any two picos. They do not have to have the same parent. In the Forever application, for example, the picos belonged to different people and represented their personal contact information.
...
A simple subscription only contains what is needed for basic secure communication.
Directional Subscription
Directional subscritpion are subscription that store roles, providing a way to identifie direction of a subscription.
Cross Engine Subscription
Cross engine subscription are subscriptions that store a host, providing subscritpions to be used across engines or possibly with 3rd party services.
Auto Accepting Subscription Request
Subscription rulest is configurable to auto accept specfied subscriptions requests. ...
At the time of writting this single use configuration is a planned feature.
Subscription Event Flow
To establish a basic subscription between pico A and pico B:
- Pico A must receive a wellKnown_Rx channel to contact Pico B. Pico A receives a
wrangler:subscription
event which includes a wellKnown_Tx attribute. wellKnown_Tx is Pico B's wellKnown_Rx . Pico A creates a channel for the subscription which is store as Rx.name
- name of subscription. name_space
- name space for subscription.my_role
- Pico B's role in the subscription.subscriber_role
- Pico A's role in the subscription.outbound_eci
- Pico A's newly created inbound ECI.channel_type
- the channel type for Pico B's yet to be created inbound ECI (the same as Pico A's).- Tx - Pico A Rx.
- Tx_verify_key - Pico A's Rx channel verifyKey.
- Tx_public_key - Pico A's Rx channel encryptionPublicKey.
- Pico B creates a Rx channel for the subscription which stores subscription information in the new channel and provides a new inbound eci for this particular subscriptionis stored as Rx along with Tx , Tx_verify_key, Tx_public_key in inbound subscription entity variable.
Pico A also raises an internalwrangler:pending_subscription
event with event with status set to outbound, with the corresponding attributes above which is stored in outbound subscription entity variable. - Upon receiving the
wrangler:pending_subscription
event, Pico B, creates a pending subscription (channel mentioned above) and raises the After storeing pending subscriptions, Pico B and Pico A raises corispondingwrangler:inbound_pending_subscription_added
event . Pico A raises the andwrangler:outbound_pending_subscription_added
event.
The state of each Picos subscription is static at this point. Pico A has an outgoing pending subscription and Pico B has an incoming pending subscription. - If Pico B wants to approve the subscription request, it raises the
wrangler:pending_subscription_approval
event with an attribute namedsubscription_name
giving the name Rx containing the Rx channel identifier of the channel/ subscription to approve. Upon successfully creating storing the subscription in established enity variable. Pico B:- sends the
wrangler:pending_subscription_approved
event with attribute status set to outbound to Pico A on Pico B'soutbound_eci
value stored in its subscription.raises the subscriptions Tx. - raises an API internal event
wrangler:subscription_added
event.
- sends the
- Upon receiving the
wrangler:pending_subscription_approved
event, Pico A adds an outbound_Tx eci to the subscription on its side and and stores the subscription in established entity variable. And raises thewrangler:subscription_added
event. Pico A then raises the wrangler:sending_key event to faclitate a key exchange with the pico it is subscribing to. - If Pico B wants to reject the subscription, it raises the
wrangler:subscription_cancellation
event (internally) with an attribute namedsubscription_name
named Rx - which is the name Rx of the channel/ subscription to reject. Pico B:- sends the
wrangler:subscriptionestablished_removal
event to Pico A on Picos B outbound_ Tx eci, which then raises the an internal APIwrangler:subscription_removed
event to itself. - raises the
wrangler:subscriptionestablished_removal
event, which which then raises the an internal APIwrangler:subscription_removed
event.
- sends the
attributes
- the attributes for this subscription. These are used for Pico B's incoming channel's attributes. Pico A then sends pico B wrangler:pending_subscription
with attribute status set to inbound. Pico A sends with that event the following attributes.Upon receiving a wrangler:
subscriptionestablished_removal
event, the pico deletes the named specified subscription from the inbound or outbound subscriptions list as appropriateestablished entity variable.
Initial Subscription Flow
...
Info |
---|
This section mentions getSubscriptionsestablished(), inbound(), outbound() and wellKnown_Rx(), which is documented in the last section, Subscription Functions. |
...
Event Domain | Event Type | Actions | Use | ||||
---|---|---|---|---|---|---|---|
wrangler | subscription | creates outbound pending subscription and sends pending_subscription event to external pico | Creates a new outbound pending subscription | ||||
wrangler | pending_subscription | creates inbound pending subscription | Creates a new inbound pending subscription | ||||
wrangler | pending_subscription_approval | sends pending_subscription_approved event with inbound_eci and outbound status to external pico and raises pending_subscription_approved with inbound status | Aprove inbound pending subscription | ||||
wrangler | wrangler | pending_ subscription_ approved | updates subscription status and outbound_eci if needed | Internally for adding aproved subscriptions | subscription_cancellation | inbound_subscription_rejection | outbound_subscription_cancellation | sends subscription_removal event with eci and status and raise the same event to self | alert Alert external pico to remove subscriptions and alert self to remove subscription |
wrangler | subscription established_removal | inbound_removal | outbound_removal | deletes channel used for subscription and updates subscription ruleset persistance | internally Internally for removing channel used for subscription |
...
- wrangler:subscription
- wrangler:outboundpending_subscription_approval
- wrangler:outbound_cancellation
- wrangler:inbound_subscription_rejection
- wrangler:subscription_cancellationwrangler:pending_subscription_approval
Events Users Might React To
- wrangler:outbound_pending_subscription_added
- wrangler:inbound_pending_subscription_addedwrangler:subscription_removed
- wrangler:subscription_added
...
wrangler:subscription (pico A)
Name | Default | Use |
---|
channel_type (optional) | " |
Tx_Rx" | describes each pico's new channel created for the subscription |
Rx_role |
(optional) | no default | describes pico A (self) in the context of the subscription |
name (optional) | string including a random English word |
If pico B is hosted on a different engine and a subscription with this full name already exists there (e.g. "namespace:name"), the new subscription will be cancelled and both picos will receive wrangler:subscription_removed after the '_added' events.
name of channel to be created. | ||
wellKnown_Tx (required) | no default | the subscription process needs one of pico B's existing eci's |
subscriber_host |
(optional) | no default | the public DNS name of the engine hosting pico B (only needed if different from pico A's) - e.g. "https://localhost:8080" |
Tx_role |
(optional) | no default | describes pico B in the context of the subscription |
wrangler:outbound_subscription_cancellation,
wrangler:inbound_subscription_rejection,
wrangler:subscription_cancellation
Name | Default | Use | subscription_name|
---|---|---|---|
Rx (required) | no subscription cancelledthe full name default | Rx eci of the subscription to cancel - both picos will receive wrangler:subscription_removedbe removed. |
wrangler:pending_subscription_approval (pico B)
Name | Default | Use |
---|---|---|
subscription_nameRx | no subscription approvedthe full name default | Rx eci of the pending subscription to approve - both picos will receive wrangler:subscription_addedbe approved. |
wrangler:outbound_pending_subscription_added (pico A)
Name | Value | attributesattrs in wrangler:subscription | |
---|---|---|---|
channel_name | full subscription name(e.g. "namespace:name")channel name | ||
channel_type | defined in wrangler:subscription | inboundchannel type | |
Rx_eci | pico A's new eci created for the subscription | ||
myRx_role | defined in wrangler:subscription | ||
name | defined in wrangler:subscription | ||
name_space | defined in wrangler:subscription | ||
relationship | string of the form my_role+"<->"+subscriber_role pico A's role | ||
status | "outbound" | ||
subscriberTx_eci | defined in wrangler:subscription | subscribereci to other pico | |
Tx_host (only included if the picos are hosted on different engines) | defined in wrangler:subscription | ||
subscriberTx_role | defined in wrangler:subscription |
example value of getSubscriptionsestablished(){channel_name
}:
Code Block |
---|
[ { "eci": "cj3lyamf30003pi0n6u39rsqs", // pico A's new eci "name"Rx": "name_space:name5sk3bNLv1aZC1w4Gz9tg7i", "typeTx": "subsBQMnQkRhpwRBspcnz4LdX8", "attributes": { "subscription_name": "name", "name_space"Tx_verify_key": "namespace6frM5S1t6i2SJh1Rp4AXDpsmwQsCqMjLagsyEKrv6HEN", "relationship: "peer 1<->peer 2", "my_role": "peer 1", "subscriber_role": "peer 2", "subscriber_eci": "cj3ly7c9m0002pl0nk2zklk4g", "status": "outbound", "attributes": "status", "subscriber_host": "http://localhost:8081", "sid": "namespace:name" } }"Tx_public_key": "DCVx2iExZb6gnumBoHz5GA2rdrt3BbsU41YUJjcF7Peq" } ] |
wrangler:inbound_pending_subscription_added (pico B)
Name | Value |
---|---|
attributes | attrs in wrangler:subscription |
channel_name | full subscription channel name(e.g. "namespace:name") |
channel_type | defined in wrangler:subscription |
my_role | subscriber_role in wrangler:subscription |
name | defined in wrangler:subscription |
name_space | defined in wrangler:subscription |
outbound_eci | pico A's new eci created for the subscription |
relationship | string of the form my_role+"<->"+subscriber_role |
status | "inbound" |
subscriber_host (only included if the picos are hosted on different engines) | public DNS name of the engine hosting pico A |
subscriber_role | my_role in wrangler:subscription |
...
Code Block |
---|
{ "eci": "cj3n6fe0w0003v8id271a0rlz", // pico B's new eci
"name": "namespace:name",
"type": "subscription",
"attributes":
{ "subscription_name": "name",
"name_space": "namespace",
"relationship": "peer 2<->peer 1",
"my_role": "peer 2",
"subscriber_role": "peer 1",
"outbound_eci": "cj3lyamf30003pi0n6u39rsqs",
"status": "inbound",
"attributes": "status",
"subscriber_host": "http://localhost:8080"} } |
wrangler:subscription_removed
...
Name | Value |
---|---|
channel_name | full subscription name(e.g. "namespace:name") |
verify_key | public cryptographic key used to verify digital signatures |
other_verify_key | the public crytpographic key from the pico that this pico is subscribed to. Used to verify digitally signed messages |
encryption_public_key | the public key that can can be used by another channel to create a shared secret, in conjuction with that channl's private key, to allow encryption and decryption. |
other_encryption_public_key | the public cryptographic key form the pico that this pico is subscribed to. It is used to allow encryption of channel messages. |
...
Subscription Functions
wellKnown_Rx()
wellKnown_Rx() returns the well known channel, e.g.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{ "id": "4H2tXa1NkexgyfEbzCFsPE", "type": "subscription", "verify_key"pico_id": "F9S4uC6bZ9pDBZMPeKUHCHrhdMkrTq9GExj8HHtGDTKq", "other_verify_key": "GjmSgqkBpAcCkt9H179pqgrQ27zPn336aaNHHHtFspAz"cjc78fh4s000b9iry4u2j2len", "encryption_public_key": "3cyFiAMRpq1Q4ciEzSoQNzAQHr9voTCu9P46Kyx6qCUz", "other_encryption_public_key": "7y9dqgw7KucvYToAguuBP4Shf1cqtnhUF93waBR799e3", "attributes": { "subscription_name": "name", "name_space": "namespace", wellKnown_Rx", "relationshiptype": "peer 1<->peer 2", "my_role": "peer 1", "subscriber_role": "peer 2", Tx_Rx", "sovrin": { "subscriber_ecidid": "cj3ly7c9m0002pl0nk2zklk4g4H2tXa1NkexgyfEbzCFsPE", "statusverifyKey": "subscribed2naJczreMuFRiDJcc3SWpP4CkXVSuViKMNq4gRmh3Tzq", // changed "attributesencryptionPublicKey": "status", "subscriber_host": "http://localhost:8081", "outbound_eci": "cj3n6fe0w0003v8id271a0rlz" } } // now available to pico A |
...
Code Block |
---|
G3Xq6daaUndzwjiP8H1WFt9fKKb2NCbZtEVwGqXLuGMC"
}
} |
established()
established() returns all established subscription in an array, e.g.
Code Block | ||
---|---|---|
| ||
[ { "eci": "cj3n6fe0w0003v8id271a0rlz", // pico B's new eci "name"Rx": "namespace:name5sk3bNLv1aZC1w4Gz9tg7i", "typeTx": "subscriptionBQMnQkRhpwRBspcnz4LdX8", "verify_key": "GjmSgqkBpAcCkt9H179pqgrQ27zPn336aaNHHHtFspAz", "other"Tx_verify_key": "F9S4uC6bZ9pDBZMPeKUHCHrhdMkrTq9GExj8HHtGDTKq6frM5S1t6i2SJh1Rp4AXDpsmwQsCqMjLagsyEKrv6HEN", "encryptionTx_public_key": "7y9dqgw7KucvYToAguuBP4Shf1cqtnhUF93waBR799e3DCVx2iExZb6gnumBoHz5GA2rdrt3BbsU41YUJjcF7Peq", } "other_encryption_public_key": "3cyFiAMRpq1Q4ciEzSoQNzAQHr9voTCu9P46Kyx6qCUz", "attributes": { "subscription_name": "name", "name_space": "namespace", "relationship": "peer 2<->peer 1", "my_role": "peer 2", "subscriber_role": "peer 1", "outbound_eci": "cj3lyamf30003pi0n6u39rsqs", "status": "subscribed", // changed "attributes: "status", "subscriber_host": "http://localhost:8080" } } |
Subscription Functions
getSubscriptions
Returns a map from subscription names to subscription objects, or various forms of this map.
...
...
...
...
getSubscriptions() with no arguments returns the entire map, e.g.
Code Block |
---|
{ "namespace:name1": ] |
outbound()
outbound() returns all outbound subscriptions in an array, e.g.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
[ { "namewellKnown_Tx": "namespace:name1B5JMLRzZnz7NQcDJuBAPSr", "attributesRx": { "status": "subscribed", ... }, ... }, "namespace:name2": { "name": "namespace:name2", "attributes": { "status": "inbound", ... }, ... } } |
...
"Q4aosn4DiPdEEpqwZZGEbh"
}
] |
inbound()
inbound() returns all inbound subscriptions in an array, e.g.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
[ { "namespace:name2Tx": { "name": "namespace:name2", "Q4aosn4DiPdEEpqwZZGEbh", "attributes": { "status"Rx": "inbound", ... }, ... } } ], "subscribed": [ {MvgUk1pHSFHqtzpUKkJErC", "namespace:name1": { "name": "namespace:name1", "Tx_verify_key": "Da2dgGAEFPLJV4bTP6kYTdphUXcJaQ5Zrnq5rnMXS5UZ", "attributesTx_public_key": { "status": "subscribed", ... }, ... } } ] } |
...
"39V93tWrxWBK2Anez4Mz6J6ec8eX3v7ZcTEdsEMSL42a"
}
] |