<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ockam</title>
    <description>The latest articles on Forem by Ockam (@build-trust).</description>
    <link>https://forem.com/build-trust</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F7330%2F39420bfd-2d48-4e72-b598-8f63a98bc1be.png</url>
      <title>Forem: Ockam</title>
      <link>https://forem.com/build-trust</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/build-trust"/>
    <language>en</language>
    <item>
      <title>How we built a Swift app that uses Rust</title>
      <dc:creator>Mrinal Wadhwa</dc:creator>
      <pubDate>Thu, 28 Dec 2023 16:51:39 +0000</pubDate>
      <link>https://forem.com/build-trust/how-we-built-a-swift-app-that-uses-rust-102f</link>
      <guid>https://forem.com/build-trust/how-we-built-a-swift-app-that-uses-rust-102f</guid>
      <description>&lt;p&gt;Yesterday our team &lt;a href="https://github.com/build-trust/ockam/blob/develop/examples/app/portals/README.md" rel="noopener noreferrer"&gt;released Portals&lt;/a&gt;, an open source Mac app built in Swift. It uses the &lt;a href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;Ockam&lt;/a&gt; Rust library to privately share TCP or HTTP services from your Mac with your friends over End-to-End Encrypted Ockam Portals. A shared service appears on their &lt;strong&gt;localhost&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;In this post, I'll dig into how the SwiftUI macOS app interacts with Rust code.&lt;/p&gt;

&lt;p&gt;If you're curious about Portals for Mac. You can learn more about it in &lt;a href="https://github.com/build-trust/ockam/blob/develop/examples/app/portals/README.md" rel="noopener noreferrer"&gt;this article&lt;/a&gt; and install is using Homebrew as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

brew install build-trust/ockam/portals


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Here's a 2 minute video of the application in action:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/eWSRNfmURJs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;h2&gt;
  
  
  Swift &amp;lt;&amp;gt; Rust
&lt;/h2&gt;

&lt;p&gt;The Portals functionality was already implemented in the Ockam Rust library. We set out to create a great macOS-native experience.&lt;/p&gt;

&lt;p&gt;Our first attempt at building the app was using Tauri. This made sense as we wanted to use the Ockam rust library and most people on our team are comfortable building things in Rust. This first version was easy to build and had all the basic functions we wanted. However, the experience of using the app wasn't great. Tauri only gave us minimal control over how the menu was rendered and what happened when a user interacts with the menu. This version of the app felt like it belonged in a 10 year old version of macOS when compared to super easy to use menubar items built into macOS Sonoma.&lt;/p&gt;

&lt;p&gt;We realized that to have the rich experience we want, we must build the app using SwiftUI.&lt;/p&gt;

&lt;p&gt;Unfortunately, we couldn't find an off-the-shelf solution, to integrate Swift and Rust, that would give us the best of both worlds; the safety of Rust, and the rich macOS-native experience of SwiftUI. After some more digging we realized we can connect the two using C-89. Rust is compatible with the C calling convention, and Swift is interoperable with Objective-C, which is a superset of C-89.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8pjr22jcdunobkgh3te.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8pjr22jcdunobkgh3te.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We wrote the Rust data structures that needed to be visible to Swift twice. One version is idiomatic in Rust and easy to use. The other version is C compatible using pointers and memory that is manually allocated with &lt;code&gt;malloc&lt;/code&gt;. We also exposed some C-compatible APIs that use raw-pointers in unsafe rust to convert the idiomatic data structures to their C-compatible versions. Finally we automatically generated a C header with the help of the &lt;code&gt;cbindgen&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;On the Swift side, we could have called the C APIs directly, but C data structures are not first class citizens in Swift. This makes them harder to use idiomatically within SwiftUI code. Instead, we chose to duplicate the data structures in Swift and convert between C and Swift. This may seem burdensome, but practically, the shared state doesn't change very often. The ability to quickly build components in SwiftUI using constructs like &lt;code&gt;if let ..&lt;/code&gt;, &lt;code&gt;ForEach&lt;/code&gt;, &lt;code&gt;enum&lt;/code&gt; etc. is super helpful and worth the tradeoff.&lt;/p&gt;

&lt;p&gt;Here's an example of the same structure in its 4 forms:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

// Rust idiomatic structure
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct LocalService {
    pub name: String,
    pub address: String,
    pub port: u16,
    pub shared_with: Vec&amp;lt;Invitee&amp;gt;,
    pub available: bool,
}

// Rust C-compatible structure
#[repr(C)]
pub struct LocalService {
    pub(super) name: *const c_char,
    pub(super) address: *const c_char,
    pub(super) port: u16,
    pub(super) shared_with: *const *const Invitee,
    pub(super) available: u8,
}

// Generated C header structure
typedef struct C_LocalService {
  const char *name;
  const char *address;
  uint16_t port;
  const struct C_Invitee *const *shared_with;
  uint8_t available;
} C_LocalService;

// Swift idiomatic structure
class LocalService {
    let name: String
    @Published var address: String?
    @Published var port: UInt16
    @Published var sharedWith: [Invitee]
    @Published var available: Bool
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The Swift app is statically linked to our Rust lib at compile time. The data flow is simple: UI interactions are sent from Swift to Rust as actions by calling C APIs, change events are emitted only by Rust, and Swift is notified using callbacks that lead to updates to the UI.&lt;/p&gt;

&lt;p&gt;Most code in the SwiftUI views looks just like any other SwiftUI application.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;

&lt;span class="kt"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;alignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sourceName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;systemName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"circle.fill"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;green&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;verbatim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Not connected"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;verbatim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unsafelyUnwrapped&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;":"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;verbatim&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Connecting"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If you're curious to learn more, checkout the code for the &lt;a href="https://github.com/build-trust/ockam/tree/develop/implementations/rust/ockam/ockam_app_lib" rel="noopener noreferrer"&gt;ockam_app_lib crate&lt;/a&gt; and the Portals &lt;a href="https://github.com/build-trust/ockam/tree/develop/implementations/swift/ockam/ockam_app" rel="noopener noreferrer"&gt;app in Swift&lt;/a&gt;. The &lt;a href="https://github.com/build-trust/ockam/blob/develop/implementations/swift/Makefile" rel="noopener noreferrer"&gt;Makefile&lt;/a&gt; in the swift folder is also a good place to explore how everything is built and linked together.&lt;/p&gt;

&lt;p&gt;If you're interested in contributing to the app's Swift or Rust code, we add new &lt;a href="https://github.com/build-trust/ockam/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22" rel="noopener noreferrer"&gt;good first issues&lt;/a&gt; every week and love helping new contributors. Join us on the &lt;a href="https://discord.ockam.io/" rel="noopener noreferrer"&gt;contributors discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/build-trust/ockam/blob/develop/examples/app/portals/README.md" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Learn more about Portals for Mac&lt;/a&gt;
&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/build-trust" rel="noopener noreferrer"&gt;
        build-trust
      &lt;/a&gt; / &lt;a href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;
        ockam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Orchestrate end-to-end encryption, cryptographic identities, mutual authentication, and authorization policies between distributed applications – at massive scale.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;🚀 &lt;em&gt;&lt;a href="https://github.com/build-trust/ockam/blob/develop/examples/app/portals/README.md" rel="noopener noreferrer"&gt;Portals for Mac&lt;/a&gt; – A macOS app built in Swift that uses the Ockam Rust library to privately share a service on your Mac with anyone, anywhere. The service is shared securely over an end-to-end encrypted and mutually authenticated Ockam Portal. Your friends will have access to it on their &lt;em&gt;localhost&lt;/em&gt;! This app is a great example of the kinds of things you can build with Ockam&lt;/em&gt; &lt;a href="https://github.com/build-trust/ockam/blob/develop/examples/app/portals/README.md" rel="noopener noreferrer"&gt;👉&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discord.gg/RAbjRr3kds" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Discord" src="https://camo.githubusercontent.com/edbdbbd5997d11f336d624bf5293aed763aedf6c08eda5f665dde891a0c66f6a/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f313037343936303838343439303833333935323f6c6162656c3d446973636f7264266c6f676f3d646973636f7264267374796c653d666c6174266c6f676f436f6c6f723d7768697465"&gt;&lt;/a&gt;
&lt;a href="https://repo-rater.eddiehub.io/rate?owner=build-trust&amp;amp;name=ockam" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/435dc7741c31f295a8930f659c38e0021c164a9fcd6d4779f68b4f05141b295a/68747470733a2f2f7265706f2d72617465722e65646469656875622e696f2f6170692f62616467653f6f776e65723d6275696c642d7472757374266e616d653d6f636b616d" alt="RepoRater"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Trust for Data-in-Motion&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Ockam is a suite of open source programming libraries and command line tools to
orchestrate end-to-end encryption, mutual authentication, key management, credential
management, and authorization policy enforcement – at massive scale.&lt;/p&gt;
&lt;p&gt;Modern applications are distributed and have an unwieldy number of
interconnections that must trustfully exchange data. To trust data-in-motion
applications need end-to-end guarantees of data authenticity, integrity, and
confidentiality. To be private and secure by-design, applications must have
granular control over every trust and access decision.…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>swift</category>
      <category>rust</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>End-to-End Encryption through Kafka - using Rust</title>
      <dc:creator>Mrinal Wadhwa</dc:creator>
      <pubDate>Fri, 10 Sep 2021 06:13:43 +0000</pubDate>
      <link>https://forem.com/build-trust/end-to-end-encryption-through-kafka-using-rust-1gcb</link>
      <guid>https://forem.com/build-trust/end-to-end-encryption-through-kafka-using-rust-1gcb</guid>
      <description>&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/build-trust" rel="noopener noreferrer"&gt;
        build-trust
      &lt;/a&gt; / &lt;a href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;
        ockam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Orchestrate end-to-end encryption, cryptographic identities, mutual authentication, and authorization policies between distributed applications – at massive scale.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Ockam is a &lt;a href="https://github.com/ockam-network/ockam" rel="noopener noreferrer"&gt;rust library&lt;/a&gt; that makes it simple for distributed applications to guarantee end-to-end integrity, authenticity, and confidentiality of data.&lt;/p&gt;

&lt;p&gt;In this post, we'll create two example programs called Alice and Bob. We'll first try the examples in dockerized form and then look at their Rust code.&lt;/p&gt;

&lt;p&gt;Alice and Bob will send each other messages, over the network, via a cloud service, through Kafka. They will mutually authenticate each other and will have a cryptographic guarantee that the &lt;em&gt;integrity, authenticity, and confidentiality&lt;/em&gt; of their messages is protected &lt;em&gt;end-to-end&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The Kafka instance, the intermediary cloud service and attackers on the network will not be able to see or change the contents of en-route messages. The application data in Kafka would be encrypted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0pfsdf3tzodn7nlaz6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0pfsdf3tzodn7nlaz6o.png" alt="End-to-End Encryption through Kafka using Ockam"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Show me the code&lt;/p&gt;

&lt;h3&gt;
  
  
  Remove implicit trust in porous network boundaries
&lt;/h3&gt;

&lt;p&gt;Modern distributed applications operate in highly dynamic environments. Infrastructure automation, microservices in multiple clouds or data centers, a mobile workforce, the Internet of Things, and Edge computing mean that machines and applications are continuously leaving and entering network boundaries. Application architects have learnt that they must lower the amount of trust they place in network boundaries and infrastructure.&lt;/p&gt;

&lt;p&gt;The vulnerability surface of our application cannot include &lt;em&gt;all code&lt;/em&gt; that may be running within the same porous network boundary. That surface is too big, too dynamic and usually outside the control of an application developer.&lt;/p&gt;

&lt;p&gt;Applications must instead take control of the security and reliability of their own data. To do this, all messages that are received over the network must prove who sent them and show that they weren't tampered with or forged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lower trust in intermediaries
&lt;/h3&gt;

&lt;p&gt;Another aspect of modern applications that can take away Alice's and Bob's ability to rely on the integrity and authenticity of incoming messages are intermediary services, such as the cloud service in our example below.&lt;/p&gt;

&lt;p&gt;Data, within distributed applications, are rarely exchanged over a single point-to-point transport connection. Application messages routinely flow over complex, multi-hop, multi-protocol routes — &lt;em&gt;across data centers, through queues and caches, via gateways and brokers&lt;/em&gt; — before reaching their end destination.&lt;/p&gt;

&lt;p&gt;Typically, when information or commands are exchanged through an intermediary service, the intermediary is able to &lt;code&gt;READ&lt;/code&gt; the messages that are being exchanged, &lt;code&gt;UPDATE&lt;/code&gt; en-route messages, &lt;code&gt;CREATE&lt;/code&gt; messages that were never sent, and &lt;code&gt;DELETE&lt;/code&gt; (never deliver) messages that were actually sent. Alice and Bob are entirely dependent on the security of such intermediaries. If the defenses of an intermediary are compromised, our application is also compromised.&lt;/p&gt;

&lt;p&gt;Transport layer security protocols are unable to protect application messages because their protection is constrained by the length and duration of the underlying transport connection. If there is an intermediary between Alice and Bob, the transport connection between Alice and the intermediary is completely different from the transport connection between Bob and the intermediary.&lt;/p&gt;

&lt;p&gt;This is why intermediaries have full &lt;code&gt;CRUD&lt;/code&gt; permissions on messages in motion.&lt;/p&gt;

&lt;p&gt;In environments like &lt;em&gt;Microservices, Internet-of-Things, and Edge Computing&lt;/em&gt; there are usually many such intermediaries. Our application’s vulnerability surface quickly grows and becomes unmanageable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mutually Authenticated, End-to-End Encrypted Secure Channels with Ockam
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ockam-network/ockam" rel="noopener noreferrer"&gt;Ockam&lt;/a&gt; that make it simple for applications to create any number of lightweight, mutually-authenticated, end-to-end encrypted secure channels. These channels use cryptography to guarantee end-to-end integrity, authenticity, and confidentiality of messages.&lt;/p&gt;

&lt;p&gt;An application can use Ockam Secure Channels to enforce &lt;strong&gt;least-privileged access&lt;/strong&gt; to commands, data, configuration, machine-learning models, and software updates that are flowing, as messages, between its distributed parts.&lt;/p&gt;

&lt;p&gt;Intermediary services and compromised software (that may be running within the same network boundary) no longer have &lt;em&gt;implicit CRUD&lt;/em&gt; permissions on our application's messages. Instead, we have granular control over access permissions – tampering or forgery of &lt;em&gt;data-in-motion&lt;/em&gt; is immediately detected.&lt;/p&gt;

&lt;p&gt;With end-to-end secure channels, we can make the vulnerability surface of our application strikingly small.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's build end-to-end protected communication between Alice and Bob, via a cloud service, through Kafka, using Ockam.&lt;/p&gt;

&lt;p&gt;We'll run two programs called Alice and Bob. We want Bob to create a secure channel listener and Alice to initiate a secure handshake (authenticated key exchange) with this listener. We'll imagine that Bob and Alice are running on two separate, far-apart, computers and all communication between them must happen via a cloud service, through Kafka.&lt;/p&gt;

&lt;p&gt;Our goal is to make the message exchange secure and guarantee that every message is delivered &lt;strong&gt;at-least once&lt;/strong&gt;. In order to establish our end-to-end Secure Channel we need a two-way exchange of messages. We'll build this using two Ockam Streams that are backed by two, single partition, Kafka topics.&lt;/p&gt;

&lt;p&gt;An Ockam Stream is a lightweight abstraction over &lt;em&gt;topics&lt;/em&gt; or &lt;em&gt;queues&lt;/em&gt; in steaming data systems like Kafka, Pulsar, RabbitMQ etc. In case of Kafka, one Ockam Stream maps to one Kafka topic. In our example below Bob will create two streams (topics). The first stream &lt;code&gt;alice_to_bob&lt;/code&gt; is for Alice to leave messages for Bob and the second stream &lt;code&gt;bob_to_alice&lt;/code&gt; is for Bob to leave messages for Alice.&lt;/p&gt;

&lt;p&gt;The cloud service, in our example, is an Ockam Node running in Ockam Hub. This node has the Kafka Add-on enabled which offers &lt;strong&gt;two&lt;/strong&gt; services for creating and managing Kafka backed Ockam Streams. The stream service is available at address &lt;code&gt;"stream_kafka"&lt;/code&gt; and index service is available at address &lt;code&gt;"stream_kafka_index"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The cloud node also has an Ockam TCP Transport listener on address: &lt;code&gt;"1.node.ockam.network:4000"&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run (Using Docker)
&lt;/h3&gt;

&lt;p&gt;To make it easy to try, we've created a Docker image that contains both Alice and Bob programs.&lt;/p&gt;

&lt;p&gt;Later in this guide we'll also show the code for these two programs in Rust.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Run Bob’s program:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm --interactive --tty ghcr.io/ockam-network/examples/kafka bob
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The Bob program creates a Secure Channel Listener to accept requests to begin an Authenticated Key Exchange. Bob also starts an Echoer worker that prints any message it receives and echoes it back on its return route.&lt;/p&gt;

&lt;p&gt;Bob then connects, over TCP, to the cloud node at &lt;code&gt;1.node.ockam.network:4000&lt;/code&gt; and requests the &lt;code&gt;stream_kafka&lt;/code&gt; service to create two Kafka backed streams - &lt;code&gt;alice_to_bob&lt;/code&gt; and &lt;code&gt;bob_to_alice&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bob then, locally, starts a receiver (consumer) for the &lt;code&gt;alice_to_bob&lt;/code&gt; stream and a sender (producer) for the &lt;code&gt;bob_to_alice&lt;/code&gt; stream.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Bob program prints two stream addresses, that exist on the cloud node, for - the &lt;code&gt;alice_to_bob&lt;/code&gt; stream and the &lt;code&gt;bob_to_alice&lt;/code&gt; stream. Copy these addresses, Alice will need them to exchange messages with Bob.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In a separate terminal window, run the Alice program:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm --interactive --tty ghcr.io/ockam-network/examples/kafka alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Alice program will stop to ask for the stream addresses that were printed in step 2. Enter them.&lt;/p&gt;

&lt;p&gt;This will tell Alice that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the route to send messages for Bob is &lt;code&gt;[(TCP, "1.node.ockam.network:4000"), alice_to_bob_stream_address]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;the route to receive messages from Bob is &lt;code&gt;[(TCP, "1.node.ockam.network:4000"), bob_to_alice_stream_address]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alice then, locally, starts a sender (producer) for the &lt;code&gt;alice_to_bob&lt;/code&gt; stream and a receiver (consumer) for the &lt;code&gt;bob_to_alice&lt;/code&gt; stream. We now have two-way communication between Alice and Bob.&lt;/p&gt;

&lt;p&gt;Alice uses the sender to initiate an authenticated key exchange with Bob.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End-to-end Secure Channel is established. Send messages to Bob and get their echoes back.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the secure channel is established, the Alice program will stop and ask you to enter a message for Bob. Any message that you enter, is delivered to Bob using the secure channel, via the cloud node, through Kafka. The echoer on Bob will echo the messages back and Alice will print it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run (Using Rust)
&lt;/h3&gt;

&lt;p&gt;Now that we understand how it works, let's look at the code for the Alice and Bob programs in Rust.&lt;/p&gt;

&lt;p&gt;If you don't have it, please &lt;a href="https://www.rust-lang.org/tools/install" rel="noopener noreferrer"&gt;install&lt;/a&gt; the latest version of Rust.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, create a new cargo project to get started:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo new --lib ockam_kafka &amp;amp;&amp;amp; cd ockam_kafka &amp;amp;&amp;amp; mkdir examples &amp;amp;&amp;amp;
  echo 'ockam = "*"' &amp;gt;&amp;gt; Cargo.toml &amp;amp;&amp;amp; cargo build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the above instructions don't work on your machine please &lt;a href="https://github.com/ockam-network/ockam/discussions/1642" rel="noopener noreferrer"&gt;post a question&lt;/a&gt;, we would love to help.&lt;/p&gt;
&lt;h4&gt;
  
  
  Bob
&lt;/h4&gt;

&lt;p&gt;Create a file at &lt;code&gt;examples/bob.rs&lt;/code&gt; and copy the below code snippet to it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// examples/bob.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SecureChannels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Routed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Unique&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Echoer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define an Echoer worker that prints any message it receives and&lt;/span&gt;
&lt;span class="c1"&gt;// echoes it back on its return route.&lt;/span&gt;
&lt;span class="nd"&gt;#[ockam::worker]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Echoer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Routed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[✓] Address: {}, Received: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.address&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Echo the message body back on its return_route.&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.return_route&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[ockam::node]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize the TCP Transport.&lt;/span&gt;
    &lt;span class="nn"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a Vault to safely store secret keys for Bob.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;vault&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create an Entity to represent Bob.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vault&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a secure channel listener for Bob that will wait for requests to&lt;/span&gt;
    &lt;span class="c1"&gt;// initiate an Authenticated Key Exchange.&lt;/span&gt;
    &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="nf"&gt;.create_secure_channel_listener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"listener"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Connect, over TCP, to the cloud node at `1.node.ockam.network:4000` and&lt;/span&gt;
    &lt;span class="c1"&gt;// request the `stream_kafka` service to create two Kafka backed streams -&lt;/span&gt;
    &lt;span class="c1"&gt;// `alice_to_bob` and `bob_to_alice`.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// After the streams are created, create:&lt;/span&gt;
    &lt;span class="c1"&gt;// - a receiver (consumer) for the `alice_to_bob` stream&lt;/span&gt;
    &lt;span class="c1"&gt;// - a sender (producer) for the `bob_to_alice` stream.&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;node_in_hub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1.node.ockam.network:4000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Unique&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bob_to_alice"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Unique&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alice_to_bob"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nn"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
        &lt;span class="nf"&gt;.stream_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stream_kafka"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.index_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stream_kafka_index"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.client_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Unique&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"bob"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nd"&gt;route!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;node_in_hub&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[✓] Streams were created on the node at: 1.node.ockam.network:4000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;bob_to_alice stream address is: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alice_to_bob stream address is: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Start a worker, of type Echoer, at address "echoer".&lt;/span&gt;
    &lt;span class="c1"&gt;// This worker will echo back every message it receives, along its return route.&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.start_worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"echoer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Echoer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// We won't call ctx.stop() here, this program will run until you stop it with Ctrl-C&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Alice
&lt;/h4&gt;

&lt;p&gt;Create a file at &lt;code&gt;examples/alice.rs&lt;/code&gt; and copy the below code snippet to it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// examples/alice.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SecureChannels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Unique&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[ockam::node]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize the TCP Transport.&lt;/span&gt;
    &lt;span class="nn"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a Vault to safely store secret keys for Alice.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;vault&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create an Entity to represent Alice.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vault&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// This program expects that Bob has created two streams&lt;/span&gt;
    &lt;span class="c1"&gt;// bob_to_alice and alice_to_bob on the cloud node at 1.node.ockam.network:4000&lt;/span&gt;
    &lt;span class="c1"&gt;// We need the user to provide the addresses of these streams.&lt;/span&gt;

    &lt;span class="c1"&gt;// From standard input, read bob_to_alice stream address.&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Enter the bob_to_alice stream address: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error stdin."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// From standard input, read alice_to_bob stream address.&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Enter the alice_to_bob stream address: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error stdin."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// We now know that the route to:&lt;/span&gt;
    &lt;span class="c1"&gt;// - send messages to bob is [(TCP, "1.node.ockam.network:4000"), a_to_b_stream_address]&lt;/span&gt;
    &lt;span class="c1"&gt;// - receive messages from bob is [(TCP, "1.node.ockam.network:4000"), b_to_a_stream_address]&lt;/span&gt;

    &lt;span class="c1"&gt;// Starts a sender (producer) for the alice_to_bob stream and a receiver (consumer)&lt;/span&gt;
    &lt;span class="c1"&gt;// for the `bob_to_alice` stream to get two-way communication.&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;node_in_hub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1.node.ockam.network:4000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
        &lt;span class="nf"&gt;.stream_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stream_kafka"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.index_service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"stream_kafka_index"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.client_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Unique&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alice"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;route!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;node_in_hub&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;a_to_b_stream_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b_to_a_stream_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// As Alice, connect to Bob's secure channel listener using the sender, and&lt;/span&gt;
    &lt;span class="c1"&gt;// perform an Authenticated Key Exchange to establish an encrypted secure&lt;/span&gt;
    &lt;span class="c1"&gt;// channel with Bob.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;route!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"listener"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="nf"&gt;.create_secure_channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[✓] End-to-end encrypted secure channel was established.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Read a message from standard input.&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Type a message for Bob's echoer:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading from stdin."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Send the provided message, through the channel, to Bob's echoer.&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;route!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"echoer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Wait to receive an echo and print it.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.receive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice received an echo: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// should print "Hello Ockam!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// This program will keep running until you stop it with Ctrl-C&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Run Bob’s program:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo run --example bob
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In a separate terminal window, in the same directory path, run the Alice program:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo run --example alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interaction will be very similar to when we ran the docker based programs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations on running an end-to-end encrypted communication through Kafka! 🥳&lt;/p&gt;

&lt;p&gt;We discussed that, in order to have a small and manageable vulnerability surface, distributed applications must use mutually authenticated, end-to-end encrypted channels. Implementing an end-to-end secure channel protocol, from scratch, is complex, error prone, and will take more time than application teams can typically dedicate to this problem.&lt;/p&gt;

&lt;p&gt;In the above example, we created a mutually authenticated, end-to-end encrypted channel running through Kafka topics combining the security of end-to-end encryption with delivery guarantees of Kafka.&lt;/p&gt;

&lt;p&gt;Ockam combines proven cryptographic building blocks into a set of reusable protocols for distributed applications to communicate security and privately. The above example only scratched the surface of what is possible with the tools that our included in Ockam.&lt;/p&gt;

&lt;p&gt;To learn more, please see our &lt;a href="https://github.com/ockam-network/ockam/blob/develop/documentation/use-cases/end-to-end-encryption-with-rust#readme" rel="noopener noreferrer"&gt;rust guide&lt;/a&gt; and &lt;a href="https://github.com/ockam-network/ockam/tree/develop/documentation/guides/rust#readme" rel="noopener noreferrer"&gt;step-by-step guide&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/build-trust" rel="noopener noreferrer"&gt;
        build-trust
      &lt;/a&gt; / &lt;a href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;
        ockam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Orchestrate end-to-end encryption, cryptographic identities, mutual authentication, and authorization policies between distributed applications – at massive scale.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>showdev</category>
      <category>rust</category>
      <category>kafka</category>
      <category>security</category>
    </item>
    <item>
      <title>Build End-to-End Encryption in 51 lines of Rust</title>
      <dc:creator>Mrinal Wadhwa</dc:creator>
      <pubDate>Thu, 12 Aug 2021 22:19:41 +0000</pubDate>
      <link>https://forem.com/build-trust/build-end-to-end-encryption-in-51-lines-of-rust-340p</link>
      <guid>https://forem.com/build-trust/build-end-to-end-encryption-in-51-lines-of-rust-340p</guid>
      <description>&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/build-trust" rel="noopener noreferrer"&gt;
        build-trust
      &lt;/a&gt; / &lt;a href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;
        ockam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Orchestrate end-to-end encryption, cryptographic identities, mutual authentication, and authorization policies between distributed applications – at massive scale.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Ockam is a &lt;a href="https://github.com/ockam-network/ockam" rel="noopener noreferrer"&gt;rust library&lt;/a&gt; that makes it simple for distributed applications to guarantee end-to-end integrity, authenticity, and confidentiality of data.&lt;/p&gt;

&lt;p&gt;In this post, we'll create two small Rust programs called Alice and Bob. Alice and Bob will send each other messages, over the network, via a cloud service. They will mutually authenticate each other and will have a cryptographic guarantee that en-route messages were not tampered or forged.&lt;/p&gt;

&lt;p&gt;The intermediary cloud service and attackers on the network will not be able to see or change the contents of en-route messages. In &lt;a href="https://github.com/ockam-network/ockam/tree/develop/documentation/guides/rust#readme" rel="noopener noreferrer"&gt;later examples&lt;/a&gt; we'll also see how we can have this end-to-end protection even when the communication path between Alice and Bob is more complex - with multiple transport connections, a variety of transport protocols and many intermediaries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiet0jafct83uggj57ygp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiet0jafct83uggj57ygp.jpeg" alt="Alice and Bob have an end-to-end protected secure channel between them that passes through a cloud service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Show me the code&lt;/p&gt;

&lt;h3&gt;
  
  
  Remove implicit trust in porous network boundaries
&lt;/h3&gt;

&lt;p&gt;Modern distributed applications operate in highly dynamic environments. Infrastructure automation, microservices in multiple clouds or data centers, a mobile workforce, the Internet of Things, and Edge computing mean that machines and applications are continuously leaving and entering network boundaries. Application architects have learnt that they must lower the amount of trust they place in network boundaries and infrastructure.&lt;/p&gt;

&lt;p&gt;The vulnerability surface of our application cannot include &lt;em&gt;all code&lt;/em&gt; that may be running within the same porous network boundary. That surface is too big, too dynamic and usually outside the control of an application developer. Applications must instead take control of the security and reliability of their own data. To do this, all messages that are received over the network must prove who sent them and show that they weren't tampered with or forged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lower trust in intermediaries
&lt;/h3&gt;

&lt;p&gt;Another aspect of modern applications that can take away Alice's and Bob's ability to rely on the integrity and authenticity of incoming messages are intermediary services, such as the cloud service in our example below.&lt;/p&gt;

&lt;p&gt;Data, within distributed applications, are rarely exchanged over a single point-to-point transport connection. Application messages routinely flow over complex, multi-hop, multi-protocol routes — &lt;em&gt;across data centers, through queues and caches, via gateways and brokers&lt;/em&gt; — before reaching their end destination.&lt;/p&gt;

&lt;p&gt;Typically, when information or commands are exchanged through an intermediary service, the intermediary is able to &lt;code&gt;READ&lt;/code&gt; the messages that are being exchanged, &lt;code&gt;UPDATE&lt;/code&gt; en-route messages, &lt;code&gt;CREATE&lt;/code&gt; messages that were never sent, and &lt;code&gt;DELETE&lt;/code&gt; (never deliver) messages that were actually sent. Alice and Bob are entirely dependent on the security of such intermediaries. If the defenses of an intermediary are compromised, our application is also compromised.&lt;/p&gt;

&lt;p&gt;Transport layer security protocols are unable to protect application messages because their protection is constrained by the length and duration of the underlying transport connection. If there is an intermediary between Alice and Bob, the transport connection between Alice and the intermediary is completely different from the transport connection between Bob and the intermediary.&lt;/p&gt;

&lt;p&gt;This is why the intermediary has full &lt;code&gt;CRUD&lt;/code&gt; permissions on the messages in motion.&lt;/p&gt;

&lt;p&gt;In environments like &lt;em&gt;Microservices, Internet-of-Things, and Edge Computing&lt;/em&gt; there are usually many such intermediaries. Our application’s vulnerability surface quickly grows and becomes unmanageable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mutually Authenticated, End-to-End Encrypted Secure Channels with Ockam
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ockam-network/ockam" rel="noopener noreferrer"&gt;Ockam&lt;/a&gt; crate makes it simple for applications to create any number of lightweight, mutually-authenticated, end-to-end encrypted secure channels. These channels use cryptography to guarantee end-to-end integrity, authenticity, and confidentiality of messages.&lt;/p&gt;

&lt;p&gt;An application can use Ockam Secure Channels to enforce &lt;strong&gt;least-privileged access&lt;/strong&gt; to commands, data, configuration, machine-learning models, and software updates that are flowing, as messages, between its distributed parts. Intermediary services and compromised software (that may be running within the same network boundary) no longer have implicit CRUD permissions on our application's messages. Instead, we have granular control over access permissions – tampering or forgery of &lt;em&gt;data-in-motion&lt;/em&gt; is immediately detected.&lt;/p&gt;

&lt;p&gt;With end-to-end secure channels, we can make the vulnerability surface of our application strikingly small.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust Example
&lt;/h2&gt;

&lt;p&gt;Let's build end-to-end protected communication between Alice and Bob, through a cloud service.&lt;/p&gt;

&lt;p&gt;We'll create two small Rust programs called Alice and Bob. We want Bob to create a secure channel listener and ask Alice to initiate a secure handshake (authenticated key exchange) with this listener. We'll imagine that Bob and Alice are running on two separate computers and this handshake must happen over the Internet.&lt;/p&gt;

&lt;p&gt;We'll also imagine that Bob is running within a private network and cannot open a public port exposed to the Internet. Instead, Bob registers a forwarding address on an Ockam Node, running as a cloud service in Ockam Hub.&lt;/p&gt;

&lt;p&gt;This node is at TCP address &lt;code&gt;1.node.ockam.network:4000&lt;/code&gt; and offers two general purpose Ockam services: &lt;em&gt;routing and forwarding.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;If you don't have it, please &lt;a href="https://www.rust-lang.org/tools/install" rel="noopener noreferrer"&gt;install&lt;/a&gt; the latest version of Rust.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, create a new cargo project to get started:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo new --lib hello_ockam &amp;amp;&amp;amp; cd hello_ockam &amp;amp;&amp;amp; mkdir examples &amp;amp;&amp;amp;
  echo 'ockam = "*"' &amp;gt;&amp;gt; Cargo.toml &amp;amp;&amp;amp; cargo build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the above instructions don't work on your machine please &lt;a href="https://github.com/ockam-network/ockam/discussions/1642" rel="noopener noreferrer"&gt;post a question&lt;/a&gt;, we would love to help.&lt;/p&gt;
&lt;h3&gt;
  
  
  Bob
&lt;/h3&gt;

&lt;p&gt;Create a file at &lt;code&gt;examples/bob.rs&lt;/code&gt; and copy the below code snippet to it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// examples/bob.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SecureChannels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;RemoteForwarder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Routed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Echoer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define an Echoer worker that prints any message it receives and&lt;/span&gt;
&lt;span class="c1"&gt;// echoes it back on its return route.&lt;/span&gt;
&lt;span class="nd"&gt;#[ockam::worker]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Worker&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Echoer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;handle_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Routed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[✓] Address: {}, Received: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.address&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Echo the message body back on its return_route.&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.return_route&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[ockam::node]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize the TCP Transport.&lt;/span&gt;
    &lt;span class="nn"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a Vault to safely store secret keys for Bob.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;vault&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create an Entity to represent Bob.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;bob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vault&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a secure channel listener for Bob that will wait for requests to&lt;/span&gt;
    &lt;span class="c1"&gt;// initiate an Authenticated Key Exchange.&lt;/span&gt;
    &lt;span class="n"&gt;bob&lt;/span&gt;&lt;span class="nf"&gt;.create_secure_channel_listener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"listener"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// The computer that is running this program is likely within a private network and&lt;/span&gt;
    &lt;span class="c1"&gt;// not accessible over the internet.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// To allow Alice and others to initiate an end-to-end secure channel with this program&lt;/span&gt;
    &lt;span class="c1"&gt;// we connect with 1.node.ockam.network:4000 as a TCP client and ask the forwarding&lt;/span&gt;
    &lt;span class="c1"&gt;// service on that node to create a forwarder for us.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// All messages that arrive at that forwarding address will be sent to this program&lt;/span&gt;
    &lt;span class="c1"&gt;// using the TCP connection we created as a client.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;node_in_hub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1.node.ockam.network:4000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;forwarder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;RemoteForwarder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node_in_hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"listener"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[✓] RemoteForwarder was created on the node at: 1.node.ockam.network:4000"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Forwarding address for Bob is:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;forwarder&lt;/span&gt;&lt;span class="nf"&gt;.remote_address&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// Start a worker, of type Echoer, at address "echoer".&lt;/span&gt;
    &lt;span class="c1"&gt;// This worker will echo back every message it receives, along its return route.&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.start_worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"echoer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Echoer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// We won't call ctx.stop() here, this program will run until you stop it with Ctrl-C&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Alice
&lt;/h3&gt;

&lt;p&gt;Create a file at &lt;code&gt;examples/alice.rs&lt;/code&gt; and copy the below code snippet to it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// examples/alice.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SecureChannels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;ockam&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[ockam::node]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize the TCP Transport.&lt;/span&gt;
    &lt;span class="nn"&gt;TcpTransport&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a Vault to safely store secret keys for Alice.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;vault&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vault&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create an Entity to represent Alice.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vault&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// This program expects that Bob has setup a forwarding address,&lt;/span&gt;
    &lt;span class="c1"&gt;// for his secure channel listener, on the Ockam node at 1.node.ockam.network:4000.&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// From standard input, read this forwarding address for Bob's secure channel listener.&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Enter the forwarding address for Bob: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading from stdin."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;forwarding_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Combine the tcp address of the node and the forwarding_address to get a route&lt;/span&gt;
    &lt;span class="c1"&gt;// to Bob's secure channel listener.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;route_to_bob_listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;route!&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;TCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1.node.ockam.network:4000"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;forwarding_address&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// As Alice, connect to Bob's secure channel listener, and perform an&lt;/span&gt;
    &lt;span class="c1"&gt;// Authenticated Key Exchange to establish an encrypted secure channel with Bob.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="nf"&gt;.create_secure_channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;route_to_bob_listener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TrustEveryonePolicy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[✓] End-to-end encrypted secure channel was established.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Read a message from standard input.&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Type a message for Bob's echoer:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading from stdin."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Send the provided message, through the channel, to Bob's echoer.&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;route!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"echoer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Wait to receive an echo and print it.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.receive&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice received an echo: {}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// should print "Hello Ockam!"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// This program will keep running until you stop it with Ctrl-C&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Run the example
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Run Bob’s program:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo run --example bob
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The Bob program creates a Secure Channel Listener to accept requests to begin an Authenticated Key Exchange. It also connects, over TCP, to the cloud node at &lt;code&gt;1.node.ockam.network:4000&lt;/code&gt; and creates a Forwarder on that cloud node. All messages that arrive at that forwarding address will be forwarded to Bob using the TCP connection that Bob created as a client.&lt;/p&gt;

&lt;p&gt;Bob also starts an Echoer worker that prints any message it receives and echoes it back on its return route.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Bob program will print a hex value which is the forwarding address for Bob on the cloud node, copy it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In a separate terminal window, in the same directory path, run the Alice program:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo run --example alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It will stop to ask for Bob's forwarding address that was printed in step 2. Give it that address.&lt;/p&gt;

&lt;p&gt;This will tell Alice that the route to reach Bob is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[(TCP, "1.node.ockam.network:4000"), forwarding_address]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When Alice sends a message along this route, the Ockam routing layer will look at the first address in the route and hand the message to the TCP transport. The TCP transport will connect with the cloud node over TCP and hand the message to it.&lt;/p&gt;

&lt;p&gt;The routing layer on the cloud node will then take the message to the forwarding address for Bob. The forwarder at that address will send the message to Bob over the TCP connection Bob had earlier created with the cloud node.&lt;/p&gt;

&lt;p&gt;Replies, from Bob, take the same path back and the entire secure channel handshake is completed is this way.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End-to-end Secure Channel is established. Send messages to Bob and get their echoes back.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the secure channel is established, the Alice program will stop and ask you to enter a message for Bob. Any message that you enter, is delivered to Bob using the secure channel, via the cloud node. The echoer on Bob will echo the messages back on the same path and Alice will print it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations on creating your first end-to-end encrypted application 🥳.&lt;/p&gt;

&lt;p&gt;We discussed that, in order to have a small and manageable vulnerability surface, distributed applications must use mutually authenticated, end-to-end encrypted channels. Implementing an end-to-end secure channel protocol, from scratch, is complex, error prone, and will take more time than application teams can typically dedicate to this problem.&lt;/p&gt;

&lt;p&gt;In the above example, we created a mutually authenticated, end-to-end encrypted channel in &lt;strong&gt;51 lines of code&lt;/strong&gt; (excluding comments).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ockam-network/ockam" rel="noopener noreferrer"&gt;Ockam&lt;/a&gt; combines proven cryptographic building blocks into a set of reusable protocols for distributed applications to communicate security and privately. The above example only scratched the surface of what is possible with the tools that our included in the &lt;code&gt;ockam&lt;/code&gt; Rust crate.&lt;/p&gt;

&lt;p&gt;To learn more, please see our use-case guide on &lt;a href="https://github.com/ockam-network/ockam/tree/develop/documentation/use-cases/end-to-end-encryption-through-kafka#readme" rel="noopener noreferrer"&gt;End-to-End Encryption through Kafka&lt;/a&gt; 🦀 and our &lt;a href="https://github.com/ockam-network/ockam/tree/develop/documentation/guides/rust#step-by-step" rel="noopener noreferrer"&gt;Step-by-Step Deep Dive&lt;/a&gt; 🦀 into the various building blocks that makeup &lt;a href="https://github.com/ockam-network/ockam" rel="noopener noreferrer"&gt;Ockam&lt;/a&gt;. &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/build-trust" rel="noopener noreferrer"&gt;
        build-trust
      &lt;/a&gt; / &lt;a href="https://github.com/build-trust/ockam" rel="noopener noreferrer"&gt;
        ockam
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Orchestrate end-to-end encryption, cryptographic identities, mutual authentication, and authorization policies between distributed applications – at massive scale.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>rust</category>
      <category>security</category>
      <category>showdev</category>
      <category>technology</category>
    </item>
  </channel>
</rss>
