Aranya Documentation An overview of the Aranya project

Walkthrough

The goal of this guide is to utilize Aranya and AQC for sending end-to-end encrypted data between applications. See the core concepts section for more details on the components used in this walkthrough. To see an example implementation with code, see the examples in the Aranya repo. This guide focuses on the high level operations and does not provide code.

This guide assumes the default policy is being used for authorization and key management.

The first step is to create config files for each Aranya daemon and run a daemon for each device that will be part of the team. At startup, the daemon will generate a keybundle containing the device identity and other cryptographic keys, if that information has not already been generated.

Once the device daemons have been started, create a team of devices on the Aranya graph by having the team owner device create the team and add the public key bundles of the other devices to the team. Each device must configure other devices on the network as sync peers in order to receive the latest updates to the Aranya graph as new commands are added to the graph. Each operation such as creating a team, adding a device to a team, assigning permissions to use labels, etc. adds commands to the Aranya graph which peers must sync via the network in order to stay up to date with the state of the team.

Once the team has been created, assign AQC labels to pairs of devices that are allowed to communicate securely with each other via AQC channels. Pairs of devices with the role of Member can create AQC channels with a certain AQC label as long as both devices have permission to use the label assigned to them by the Operator. Once an AQC channel has been created between two devices, they can create bidirectional and unidirectional QUIC streams to securely send and receive data with each other via the QUIC transport.

Building Aranya Daemon

Pre-built daemon executable for various platforms are attached to the latest release. If there is already an executable available for your architecture, building the daemon is optional.

The following platforms are currently supported:

  • linux/amd64
  • linux/arm64
  • macos/amd64

Other unix-based platforms with matching hardware architectures are likely supported.

Platforms that are not yet supported:

  • windows
  • linux/arm32

The following dependencies must be present on the machine before building Aranya:

Checkout the aranya repo locally.

To build the daemon, invoke:

$ cargo make build

The daemon executable will be generated at: <repo>/target/release/aranya-daemon

Daemon Config Files

At runtime, each daemon loads a configuration file. This config file includes syncer network address configuration and a path to non-volatile Aranya graph storage. A complete example of a daemon configuration file can be found here.

Based on this example, create a configuration file for each device daemon. Remember to change the IP addresses, ports, and other device-specific values for each device.

Or, directly use the daemon configuration files from the C example. This example has configs for each device in the tutorial.

Now that the daemons have been configured, we can run them!

Running The Aranya Daemon

Once the daemon has been built, it can be run like this:

$ target/release/aranya-daemon <path to daemon config file>

Creating an Aranya Team

We are now ready to create an Aranya team and set up AQC channels to communicate between devices on the team. The step-by-step process for each of these portions is listed below, followed by an outline of the relevant APIs and reference documentation needed to do the integration in the desired language.

  1. Create a daemon config file for each device that will be on the Aranya team.
  2. Start the daemon executables for each device on the Aranya team.
  3. Owner device creates a team.
  4. Owner device adds other devices to team using their public key bundles: admin device, operator device, member devices.
  5. Each device on the team should configure sync peers in order to stay up-to-date with the latest graph commands that have been published for the team.

Sending and Receiving Data With AQC Channels

Once an Aranya team has been created, AQC labels and channels can be created, and data can be sent via those AQC channels:

  1. Admin device creates AQC labels.
  2. Operator device assigns labels to devices to grant them permission to use AQC channels with those labels.
  3. Operator assigns network identifiers to each device that needs to communicate via an AQC channel (e.g. operator assigns localhost:1010 to member device A). AQC uses network identifiers to configure the network address, port, etc. that an AQC client should connect to another peer’s AQC server at.
  4. Member devices create AQC channels with a peer devices on the network using assigned AQC labels. A PSK is generated by Aranya and pre-shared between devices to secure TLS communications via the QUIC transport. Two member devices that have the same label assigned to them may create an AQC channel between themselves using that label.
  5. Member devices create bidirectional or unidirectional AQC QUIC streams on existing AQC channels for sending/receiving AQC data with another peer device on the network.
  6. Member devices send/recv data securely via AQC QUIC streams.

Getting Started With Rust

Rust Example

Rust example

Rust API Docs

Rust API

Method Cheat Sheet

Client methods:

  • create_team() - Create an Aranya team
  • add_team() - Add an Aranya team to a device

Team methods:

  • add_device_to_team() - Add a device to the Aranya team
  • add_sync_peer() - Add peer to sync with
  • assign_aqc_net_identifier() - Assign an AQC network identifier to a device
  • create_label() - Create a new AQC label
  • assign_label() - Assign an AQC label to a device

AqcChannels methods:

  • create_bidi_channel() - Create a bidirectional AQC channel

AqcBidiChannel methods:

  • create_bidi_stream() - Create a bidirectional AQC stream
  • receive_stream() - Receive an AQC stream

AqcPeerStream methods:

  • into_bidi() - Tries to convert stream into bidi stream
  • into_receive() - Tries to convert stream into receive stream

AqcBidiStream methods:

  • send() - Send data via the stream
  • receive() - Receive data via the stream
  • try_receive() - Try to receive data via the stream

AqcReceiveStream methods:

  • receive() - Receive data via the stream
  • try_receive() - Try to receive data via the stream

Getting Started With C

C Example

C Example

C API Docs

C API

Method Cheat Sheet

  • aranya_create_team() - Create an Aranya team
  • aranya_add_team() - Add an Aranya team to a device
  • aranya_add_device_to_team() - Add a device to the Aranya team
  • aranya_add_sync_peer() - Add peer to sync with
  • aranya_aqc_assign_net_identifier() - Assign an AQC network identifier to a device
  • aranya_create_label() - Create a new AQC label
  • aranya_assign_label() - Assign an AQC label to a device
  • aranya_aqc_create_bidi_channel() - Create a bidirectional AQC channel
  • aranya_aqc_receive_channel() - Receive an AQC channel
  • aranya_aqc_bidi_create_bidi_stream() - Create a bidirectional AQC stream
  • aranya_aqc_bidi_stream_send() - Send data via bidirectional stream
  • aranya_aqc_bidi_stream_try_recv() - Try to receive data via a bidirectional stream

Security Considerations

This getting started guide is intended as an example to be run on a single machine. As such, a single machine is used to generate all key bundles and run all daemons under a single user account.

In production, each Aranya device key bundle should be created under separate user accounts on their respective machines and daemon working directories should only grant read-write access to their respective daemon executable. This avoids a single access point for all Aranya device keys in case a machine or user account is compromised.

Policy

Permission for devices to execute the operations outlined in this guide are determined by the implemented policy.