End-to-end encryption and mutual authentication for distributed applications.

Overview

Ockam

Rust and Elixir libraries for end-to-end encrypted, mutually authenticated, secure communication.

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

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.

Ockam is a suite of programming libraries and infrastructure that makes it simple for our applications to guarantee end-to-end integrity, authenticity, and confidentiality of data.

We no longer have to implicitly depend on the defenses of every machine or application within the same, usually porous, network boundary. Our application's messages don't have to be vulnerable at every point, along their journey, where a transport connection terminates.

Instead, our application can have a strikingly smaller vulnerability surface and easily make granular authorization decisions about all incoming information and commands.


Features

  • End-to-end encrypted, mutually authenticated secure channels.
  • Key establishment, rotation, and revocation - for fleets, at scale.
  • Identity profiles isolated by privacy contexts.
  • Attribute-based Access Control - credentials with selective disclosure.
  • Add-ons for a variety of operating environments, transport protocols, and cryptographic hardware.
  • Libraries for multiple languages - Rust, Elixir (more on the roadmap).

Hello Ockam

Let's write a simple example to create an encrypted secure channel between Alice and Bob. When a message is sent through this channel it will be encrypted when it enters the channel and decrypted just before it exits the channel.

For the purpose of our first example, we'll create a local channel within one program. In later examples, you'll see that it's just as easy to create end-to-end protected channels over multi-hop, multi-protocol transport routes:

  1. Install Rust

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  2. Setup a new cargo project to get started.

    cargo new --lib hello_ockam && cd hello_ockam && mkdir examples &&
      echo 'ockam = "*"' >> Cargo.toml && cargo build
    

    If the above instructions don't work on your machine, please post a question, we would love to help.

  3. Create a file at examples/hello.rs and copy the below code snippet to it.

    // examples/hello.rs
    
    use ockam::{route, Context, Entity, Result, TrustEveryonePolicy, Vault};
    
    #[ockam::node]
    async fn main(mut ctx: Context) -> Result<()> {
        // Create a Vault to safely store secret keys for Alice and Bob.
        let vault = Vault::create(&ctx).await?;
    
        // Create an Entity to represent Bob.
        let mut bob = Entity::create(&ctx, &vault).await?;
    
        // Create a secure channel listener for Bob that will wait for requests to
        // initiate an Authenticated Key Exchange.
        bob.create_secure_channel_listener("bob", TrustEveryonePolicy).await?;
    
        // Create an entity to represent Alice.
        let mut alice = Entity::create(&ctx, &vault).await?;
    
        // As Alice, connect to Bob's secure channel listener and perform an
        // Authenticated Key Exchange to establish an encrypted secure channel with Bob.
        let channel = alice.create_secure_channel("bob", TrustEveryonePolicy).await?;
    
        // Send a message, ** THROUGH ** the secure channel,
        // to the "app" worker on the other side.
        //
        // This message will automatically get encrypted when it enters the channel
        // and decrypted just before it exits the channel.
        ctx.send(route![channel, "app"], "Hello Ockam!".to_string()).await?;
    
        // Wait to receive a message for the "app" worker and print it.
        let message = ctx.receive::<String>().await?;
        println!("App Received: {}", message); // should print "Hello Ockam!"
    
        // Stop all workers, stop the node, cleanup and return.
        ctx.stop().await
    }
    
  4. Run the example

    cargo run --example hello
    

Congratulations on running your first Ockam program 🥳 .

A lot happened when you ran this small example. It created a secure vault, spawned workers to represent entities, established a mutually authenticated channel and then routed a message through that channel. This involved running cryptographic protocols for generating keys, authenticating as an entity, performing an authenticated key exchange and exchanging messages with authenticated encryption.

To learn more about how we make these powerful cryptographic protocols simple to use, please have a look at our step-by-step guide where we introduce the building blocks in Ockam.


Concepts

Here's a high-level view of the core ideas in Ockam.

Ockam

To learn more please see our step-by-step guide.

Next Steps

  • Build End-to-End Encryption with Rust: In this hands-on guide, we create two small Rust programs called Alice and Bob. Alice and Bob send each other messages, over the network, via a cloud service. They mutually authenticate each other and have a cryptographic guarantee that the integrity, authenticity, and confidentiality of their messages is protected end-to-end. 👉

  • Build End-to-End Encryption through Kafka: In this guide, we show two programs called Alice and Bob. Alice and Bob send each other messages, over the network, via a cloud service, through Kafka. They mutually authenticate each other and have a cryptographic guarantee that the integrity, authenticity, and confidentiality of their messages is protected end-to-end. The Kafka instance, the intermediary cloud service and attackers on the network are not be able to see or change the contents of en-route messages. The application data in Kafka is encrypted. 👉

  • How to end-to-end encrypt all application layer communication: In this hands-on guide, we'll create two simple Rust programs to transparently tunnel arbitrary application layer communication through Ockam's end-to-end encrypted, mutually authenticated secure channels. These example programs are also available in a docker image so you can try them without setting up a rust toolchain. 👉

  • Build a secure access tunnel to a service in a remote private network: In this guide, we'll write a few simple Rust programs to programmatically create secure access tunnels to remote services and devices that are running in a private network, behind a NAT. We'll then tunnel arbitrary communication protocols through these secure tunnels. 👉

  • Step-by-Step Deep Dive: In this step-by-step guide we write many small rust programs to understand the various building blocks that make up Ockam. We dive into Node, Workers, Routing, Transport, Secure Channels and more. 👉

License

The code in this repository is licensed under the terms of the Apache License 2.0.


Continuous Integration Contributor Covenant


Comments
  • Diagnose `Cannot drop a runtime ...` error in rust nodes

    Diagnose `Cannot drop a runtime ...` error in rust nodes

    This error shows up often

    thread 'tokio-runtime-worker' panicked at 'Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context.', /Users/mrinal/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.19.2/src/runtime/blocking/shutdown.rs:51:21
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

    We love helping new contributors! If you have questions or need help as you work on your first Ockam contribution, please leave a comment on this discussion. If you're looking for other issues to contribute to, checkout issues labeled - https://github.com/build-trust/ockam/labels/good%20first%20issue or https://github.com/build-trust/ockam/labels/help%20wanted

    Type: Bug help wanted Component: Core 
    opened by mrinalwadhwa 43
  • add `no_main` arg support in ockam::node macro

    add `no_main` arg support in ockam::node macro

    opened by pro465 30
  • fix(rust): Check address before creating stuff

    fix(rust): Check address before creating stuff

    Current Behavior

    described in #3061

    Proposed Changes

    fixes #3061.

    Checks

    auto-merge 
    opened by pro465 21
  • Implement the `ockam secure-channel show` command

    Implement the `ockam secure-channel show` command

    Currently:

    > ockam node create n1 --tcp-listener-address 127.0.0.1:6001
    > ockam node create n2 --tcp-listener-address 127.0.0.1:6002
    
    Node:
      Name: n2
      ...
        Service:
          Type: Secure Channel Listener
          Address: /service/api
          Route: /ip4/127.0.0.1/tcp/6002/service/api
          Identity: P7dc502c795201c2d816749ea45ff51a416dce16ef0fe1b65ab4a642899e3b4d8
          Authorized Identities:
            - P7dc502c795201c2d816749ea45ff51a416dce16ef0fe1b65ab4a642899e3b4d8
      ...
    

    Since n2 gets a secure channel listener at /ip4/127.0.0.1/tcp/6002/service/api We can create secure channels from n1 to this listener

    > ockam secure-channel create --from n1 --to /ip4/127.0.0.1/tcp/6002/service/api \
         --authorized-identifier P7dc502c795201c2d816749ea45ff51a416dce16ef0fe1b65ab4a642899e3b4d8
    /service/9a87006896ec1920da7fdbb233449d24
    

    The created secure channel has the following properties:

    1. an address /service/9a87006896ec1920da7fdbb233449d24
    2. a route to the secure channel listener that it connects to /ip4/127.0.0.1/tcp/6002/service/api
    3. the identifier it uses for itself
    4. a list of identifiers that are authorized to be presented by the secure channel listener.

    Some of this secure channel info is stored in a service registry when they are created. Some of it is not. https://github.com/build-trust/ockam/blob/c397c97078dc4962d29d0180d32e579d3ca633c3/implementations/rust/ockam/ockam_api/src/nodes/service/secure_channel.rs#L42-L46

    The command to create the secure channels is defined here https://github.com/build-trust/ockam/tree/develop/implementations/rust/ockam/ockam_command/src/secure_channel

    Desired:

    We want to add a ockam secure-channel show command that would show info of a secure channel given its address with all of the above details.

    Related #3188


    We love helping new contributors! If you have questions or need help as you work on your first Ockam contribution, please leave a comment on this discussion. If you're looking for other issues to contribute to, checkout issues labeled - https://github.com/build-trust/ockam/labels/good%20first%20issue or https://github.com/build-trust/ockam/labels/help%20wanted

    good first issue help wanted Implementation: Rust Component: Command 
    opened by mrinalwadhwa 20
  • Add unit test coverage to entity package

    Add unit test coverage to entity package

    Thank you for sending a pull request :heart:

    Checklist

    Please review the guidelines for contributing code to this repository. And check [x] all the boxes that apply:

    • [x] This request pulls a feature/bugfix branch (right side) from my fork. Not my master.
    • [ ] This request pulls against ockam-network/ockam’s develop branch (left side).
    • [x] Build succeeds ./build with no linter warnings or test failures.
    • [x] All code matched our code formatting conventions.
    • [x] Commit messages match our conventions and all commits are signed.
    • [x] This request includes tests and documentation for all new code.

    Proposed Changes

    Please describe the changes in your pull request.

    If this pull request resolves an already recorded bug or a feature request, be sure to link to that issue.

    opened by malnick 18
  • Support DID Auth

    Support DID Auth

    DID Auth: https://github.com/WebOfTrustInfo/rwot6-santabarbara/blob/master/final-documents/did-auth.md https://www.slideshare.net/SSIMeetup/introduction-to-did-auth-with-markus-sabadello

    Status: Abandoned Priority: Medium Status: In Progress Type: Enhancement 
    opened by mrinalwadhwa 15
  • feat(rust): add examples section to ockam message send command's help

    feat(rust): add examples section to ockam message send command's help

    PR purpose: Address issue #3257

    Current Behaviour

    ockam message send --help

    does not display any examples.

    Desired Behaviour

    As part of the help, the following examples section should be shown:

    EXAMPLES
    
        # Create two nodes
        > ockam node create n1
        > ockam node create n2
    
        # Send a message to the uppercase service on node n1
        > ockam message send hello --to /node/n1/service/uppercase
        HELLO
    
        # Send a message to the uppercase service on node n1 from node n1
        > ockam message send hello --from /node/n2 --to /node/n1/service/uppercase
        HELLO
    
        # Create a secure channel from node n1 to the api service on node n1
        # Send a message through this encrypted channel to the uppercase service
        > ockam secure-channel create --from /node/n1 --to /node/n2/service/api \
            | ockam message send hello --from /node/n1 --to -/service/uppercase
        HELLO
    
    LEARN MORE
    
    auto-merge 
    opened by chrischiedo 14
  • Example - Node and Workers

    Example - Node and Workers

    HELLO NODE AND WORKERS

    Create a local Ockam Node - A

    • Create a local "echoer" Worker on A
    • Send the local "echoer" Worker a message
    • Receive a reply from the local "echoer"
    opened by mrinalwadhwa 14
  • Refactor `ockam transport ...` commands into `ockam tcp-...` commands

    Refactor `ockam transport ...` commands into `ockam tcp-...` commands

    Create

    We currently have

    ockam transport create tcp-connector ...
    ockam transport create tcp-listener ...
    

    We want to change to:

    ockam tcp-connection create ...
    ockam tcp-listener create ...
    

    Without changing their behavior.

    List

    We currently have

    ockam transport list --node n1
    

    This will list both tcp listeners and tcp connection.

    We want to change it to

    ockam tcp-connection list --node n1
    

    to list connections, and

    ockam tcp-listener list --node n1
    

    to list listeners

    Delete

    We currently have

    ockam transport delete --node n1 <TRANSPORT_ID>
    

    which will delete either connections or listeners.

    We want to change it to:

    ockam tcp-listener delete --node n1 <TRANSPORT_ID>
    

    and

    ockam tcp-connection delete --node n1 <TRANSPORT_ID>
    

    Code

    The code for these commands is here: https://github.com/build-trust/ockam/tree/develop/implementations/rust/ockam/ockam_command/src/transport


    Related: #3077 #3078

    good first issue help wanted Implementation: Rust Component: CLI Component: Command 
    opened by mrinalwadhwa 13
  • Make `ockam message send ...` support `-` to represent STDIN in its addr argument

    Make `ockam message send ...` support `-` to represent STDIN in its addr argument

    Current Behaviour:

    Here are two example commands:

    » ockam node create
    
    Node Created!
    
    Node:
      Name: 7ad4e471
      Status: Running
      API Address: 127.0.0.1:53552
      ...
    

    then:

    » ockam message send /ip4/127.0.0.1/tcp/53552/ockam/uppercase "hello"
    HELLO
    

    Desired Behaviour:

    We want the following to work (note the hyphen)

    » echo "/ockam/uppercase" | ockam message send /ip4/127.0.0.1/tcp/53552/- "hello"
    HELLO
    

    also

    » echo "/ip4/127.0.0.1/tcp/53552/" | ockam message send -/ockam/uppercase "hello"
    HELLO
    

    ockam message send ... should inspect addr (its first argument) to see if contains -, if it does, replace the hyphen with piped input read from STDIN

    This will allow us to chain various ockam commands

    The code for this is here: https://github.com/build-trust/ockam/blob/0df0d9658b44b772d24e7ac3ea95313f61c15c21/implementations/rust/ockam/ockam_command/src/message/send.rs#L8-L12


    We love helping new contributors! If you have questions or need help as you work on your first Ockam contribution, please leave a comment on this discussion. If you're looking for other issues to contribute to, checkout issues labeled - https://github.com/build-trust/ockam/labels/good%20first%20issue or https://github.com/build-trust/ockam/labels/help%20wanted

    good first issue help wanted Implementation: Rust Component: Command 
    opened by mrinalwadhwa 13
  • Example - Identities and Mutual Authentication

    Example - Identities and Mutual Authentication

    Continuing from #952

    HELLO IDENTITIES AND MUTUAL AUTHENTICATION

    On A:

    • Create a Vault
    • Create an Identity Profile

    On B:

    • Create a Vault
    • Create an Identity Profile

    A proves control of its Identity Profile to B over the A -> Z -> B route B proves control of its Identity Profile to A over the B -> Z -> A route

    opened by mrinalwadhwa 13
  • Improve NodeManager resource management

    Improve NodeManager resource management

    Currently NodeManager plays 2 roles:

    1. Being a worker that responds to requests
    2. Owning node's main resources

    That creates some complications, (e.g. mentioned in this thread).

    My suggestion is:

    1. Rename NodeManager to NodeManagerWorker and let it only handle requests
    2. Move all state to a separate structure (name NodeManager is still good here)
    3. Make possible having shared access to NodeManager by either wrapping the whole structure in Arc<Mutex<_>> or replacing its internals with thread-safe shared access options (like RwLock)

    3 would be great as a separate PR

    Type: Enhancement help wanted Implementation: Rust Component: Core 
    opened by SanjoDeundiak 0
  • docs: added docker instructions to the exercises

    docs: added docker instructions to the exercises

    Current Behavior

    This PR addresses the challenges users may encounter when conducting the learning exercises in a local development environment. An example of an issue is #3521 , more examples can be found in the help thread.

    Proposed Changes

    The PR adds instructions on using a Docker container for the exercises featured in the main README.md. The user may still proceed with a local install should they choose to. The benefit is a better learning experience for the user and less time spent by the Ockam team on answering questions about a user's local environment, which can be difficult and time-consuming to debug.

    There is a price to pay with this setup. The first compile session will take a few minutes due to updates to crates.io index. In my opinion, the tradeoff of less time spent in helping users debug local environment issues makes this worth it for all parties.

    Checks

    opened by karl-cardenas-coding 5
  • clang not found

    clang not found

    When attempting to go through the hello work example on my Mac (M1 Monterey 12.6) I keep getting the same error of clang not found. Regardless of the number of times I try to install clang through the automated prompt, the software is not found.

    Below is a snipped out of the error output:

              sh: line 1:  1592 Abort trap: 6           /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -find clang 2> /dev/null
              cc: error: sh -c '/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -find clang 2> /dev/null' failed with exit code 34304: (null) (errno=Invalid argument)
              xcode-select: Failed to locate 'clang', requesting installation of command line developer tools.
    
    
    error: linking with `cc` failed: exit status: 72
    

    This error occurs when the cargo build command is invoked.

    Solution

    I am sharing the solution here in case others stumble into this error when getting started. It seems like every time the OS version is upgraded, Xtools preference location is not linked to the latest. You can read more about this issue in this thread.

    Issue the following command in your Terminal session to resolve the issue:

    sudo xcode-select -switch /Library/Developer/CommandLineTools
    
    opened by karl-cardenas-coding 5
  • feat(rust): upgrade to clap v4

    feat(rust): upgrade to clap v4

    Current Behavior

    clap & clap_complete v3 are used

    Proposed Changes

    • upgrade clap to v4.0.0.0-rc.2 & clap_complete to v4.0.0-rc.1
    • address v3 & v4 deprecation warnings
    • transition derives to command/arg
    • deactivate mut_subcommand for "help" (causes runtime error) disable_help_flag and add global help arg
    • unify help templates with new default help styling (lower-/uppercase)

    Notes

    Changing the about text for the help for subcommands was removed as this is not possible with the new version utilizing mut_subcommand. Formatting and styling the help is no longer possible the same way as in v3. clap::Command::help_template formats the variables (e.g. {usage}) now with the new style (bold/underlined) but within the template there is no support for bold/underline in custom strings.

    Checks

    opened by hargut 1
  • feat(rust): extend the declarative config support

    feat(rust): extend the declarative config support

    Scope

    Being able to execute a set of commands after a node is created.

    This PR contains work that is out of the mentioned scope but it makes progress based on the design issue. It will serve as a starting point that works for a specific use case. We can keep refactoring the internals while we progress in the design issue.

    How to test

    (Based on this demo)

    Export the commands you want to execute after a node is created:

    ockam forwarder create blue --at /project/default --to /node/blue --export blue.json --export-section on-node-init --depends-on blue-outlet
    ockam tcp-outlet create --at /node/blue --from /service/outlet --to 127.0.0.1:5000 --export blue.json --export-as blue-outlet --export-section on-node-init
    

    Run the necessary context (enroll + exporting the project.json data).

    Create the node:

    ockam node create blue --project project.json --config blue.json
    
    opened by adrianbenavides 0
Releases(ockam_v0.76.0)
Owner
Ockam | Trust for Data-in-Motion
Tools for mutual authentication and end-to-end encrypted messaging between distributed applications, in any environment, anywhere.
Ockam | Trust for Data-in-Motion
Nym provides strong network-level privacy against sophisticated end-to-end attackers, and anonymous transactions using blinded, re-randomizable, decentralized credentials.

The Nym Privacy Platform The platform is composed of multiple Rust crates. Top-level executable binary crates include: nym-mixnode - shuffles Sphinx p

Nym 596 Sep 22, 2022
An open source desktop wallet for nano and banano with end-to-end encrypted, on chain messaging using the dagchat protocol.

An open source wallet with end-to-end encrypted, on chain messaging for nano and banano using the dagchat protocol.

derfarctor 15 Jul 19, 2022
NymDrive is a complete, end-to-end encrypted file syncing daemon that runs over the Nym network.

NymDrive NymDrive is a complete, end-to-end encrypted file syncing daemon that runs over the Nym network. Features Active file monitoring of changes i

Hans Bricks 16 Jul 12, 2022
Meta-repository for Miscreant: misuse-resistant symmetric encryption library with AES-SIV (RFC 5297) and AES-PMAC-SIV support

The best crypto you've never heard of, brought to you by Phil Rogaway A misuse resistant symmetric encryption library designed to support authenticate

miscreant. 483 Sep 15, 2022
DexiosGUI - Simple cross-platform drag-and-drop Dexios file encryption

DexiosGUI Simple cross-platform drag-and-drop Dexios file encryption. Latest Windows x64 release is here. DexiosGUI is a Qt/C++ app for encrypt and de

Fabrice Corraire 4 Jul 25, 2022
A safe implementation of the secure remote password authentication and key-exchange protocol (SRP), SRP6a and legacy are as features available.

Secure Remote Password (SRP 6 / 6a) A safe implementation of the secure remote password authentication and key-exchange protocol (SRP version 6a). Ver

Sven Assmann 10 Aug 1, 2022
rabe is an Attribute Based Encryption library, written in Rust

Rabe rabe is a rust library implementing several Attribute Based Encryption (ABE) schemes using a modified version of the bn library of zcash (type-3

Fraunhofer AISEC 50 Sep 12, 2022
WebAssembly wrapper of the rage encryption library

rage-wasm: WebAssembly wrapper of rage rage is a simple, modern, and secure file encryption tool, using the age format. It features small explicit key

Kan-Ru Chen 30 Apr 17, 2022
A Rust library for lattice-based additive homomorphic encryption.

Cupcake Cupcake is an efficient Rust library for the (additive version of) Fan-Vercauteren homomorphic encryption scheme, offering capabilities to enc

Facebook Research 358 Sep 23, 2022
A Rust binary for file encryption to multiple participants.

Kaspa-miner A Rust binary for file encryption to multiple participants. Installation From Sources With Rust's package manager cargo, you can install k

Elichai Turkel 26 Aug 18, 2022
A Rust Library of China's Standards of Encryption Algorithms (SM2/3/4)

Libsm Libsm is an open source pure rust library of China Cryptographic Algorithm Standards. It is completed by a collaborative effort between the Cryp

CITAHub 134 Sep 20, 2022
In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

陈年旧事。 32 Sep 8, 2022
A secure file encryption utility, written in rust.

Dexios Dexios What is it? Building notes Checksums Performance Output file sizes Environment Variables Key Inputs Usage Examples To Do What is it? Dex

brxken 138 Sep 21, 2022
The Hybrid Public Key Encryption (HPKE) standard in Python

Hybrid PKE The Hybrid Public Key Encryption (HPKE) standard in Python. hybrid_pke = hpke-rs ➕ PyO3 This library provides Python bindings to the hpke-r

Cape Privacy 2 Aug 23, 2022
Project Masterpass is a deterministic databaseless key management algorithm, aimed to help those who cannot protect their encryption keys in storage

Project Masterpass (working title) Attention! This project is still under heavy development, and SHOULD NOT be used in practice, as the algorithms cou

Gyorgy Wang 2 Sep 11, 2022
Use Touch ID / Secure Enclave for SSH Authentication!

SeKey About SeKey is a SSH Agent that allow users to authenticate to UNIX/Linux SSH servers using the Secure Enclave How it Works? The Secure Enclave

SeKey 2.3k Sep 8, 2022
LibreAuth is a collection of tools for user authentication.

LibreAuth is a collection of tools for user authentication. Features Password / passphrase authentication no character-set limitation reason

Rodolphe Bréard 244 Sep 15, 2022
A distributed, cryptographically-verifiable blog / social network

FeoBlog FeoBlog is a distributed blogging platform. It takes a lot of its inspiration from Mastodon and Scuttlebutt. It aims to solve a couple of prob

Cody Casterline 69 Jun 10, 2022
FS-DKR: One Round Distributed Key Rotation

FS-DKR: One Round Distributed Key Rotation Intro In this note we aim to re-purpose the Fouque-Stern Distributed Key Generation (DKG) to support a secu

[ZenGo X] 25 Jul 22, 2022