diff --git a/docs/images/image1.png b/docs/images/image1.png new file mode 100644 index 0000000..bb02598 Binary files /dev/null and b/docs/images/image1.png differ diff --git a/docs/images/image2.png b/docs/images/image2.png new file mode 100644 index 0000000..29008e5 Binary files /dev/null and b/docs/images/image2.png differ diff --git a/docs/images/image3.png b/docs/images/image3.png new file mode 100644 index 0000000..c96a5d4 Binary files /dev/null and b/docs/images/image3.png differ diff --git a/docs/images/image4.png b/docs/images/image4.png new file mode 100644 index 0000000..f59845a Binary files /dev/null and b/docs/images/image4.png differ diff --git a/docs/images/image5.png b/docs/images/image5.png new file mode 100644 index 0000000..ca24ab1 Binary files /dev/null and b/docs/images/image5.png differ diff --git a/docs/images/image6.png b/docs/images/image6.png new file mode 100644 index 0000000..4bc6d76 Binary files /dev/null and b/docs/images/image6.png differ diff --git a/docs/images/image7.png b/docs/images/image7.png new file mode 100644 index 0000000..b214195 Binary files /dev/null and b/docs/images/image7.png differ diff --git a/docs/overview.md b/docs/overview.md new file mode 100644 index 0000000..861fa91 --- /dev/null +++ b/docs/overview.md @@ -0,0 +1,194 @@ +**ARANYA OVERVIEW** + +Table of Contents + +- [What is Aranya?](#what-is-aranya) +- [What can I use Aranya for?](#what-can-i-use-aranya-for) +- [What does Aranya mean for me?](#what-does-aranya-mean-for-me) + - [Capabilities](#capabilities) +- [Aranya Platform](#aranya-platform) + - [Deployment Ecosystem](#deployment-ecosystem) +- [Integration/API Overview](#integrationapi-overview) + - [Aranya APIs](#aranya-apis) + - [Configuration File API](#configuration-file-api) + - [Initialization API](#initialization-api) + - [Access Control APIs](#access-control-apis) + - [Data Exchange APIs](#data-exchange-apis) + - [Transport APIs](#transport-apis) +- [Glossary](#glossary) + +# What is Aranya? + +Aranya is an **access governance and secure data exchange platform for organizations to control their critical data and services**. Access governance is a mechanism to define, enforce, and maintain the set of rules and procedures to secure your system\'s behaviors. Data governance is a more narrowed approach for applying the same mechanism to specifically address access permissions of all data in the system. + +Aranya ensures that your system\'s process for managing access controls to data or services is aligned with your organization\'s objectives and adheres to policy requirements. Defining the set of policies by specifying roles and permissions enables you to **safeguard sensitive information, maintain compliance, mitigate the risk of unauthorized data exposure, and grant appropriate access.** Aranya\'s decentralized platform allows you to define and enforce these sets of policies to secure and access your resources. + +The platform is **delivered and integrated into your system as a library** for policy-driven access controls and secure data exchange. The library is deployed on endpoints, integrating into applications which require granular access controls over their data and services. Endpoints can entrust Aranya with their data protection and access controls so that other applications running on the endpoint need only to focus on using the data for their intended functionality. + +A key discriminating attribute of Aranya is the decentralized, zero trust architecture. Through the integration of the library, access governance is implemented without the need for a connection back to centralized IT infrastructure. With Aranya\'s decentralized architecture, if two endpoints are connected to each other, but not back to the cloud or centralized infrastructure, **governance over data and applications will be synchronized between peers** **and further operations will continue uninterrupted.** + +# What can I use Aranya for? + +- **Secure Sensitive Data:** Ensure your data is secured from unauthorized access or potential breaches using cryptographic algorithms to encrypt the data. + +- **Data Protection and Privacy:** Granular controls which can grant or revoke access, defined through policy that dictate whether an entity can or can\'t access data. + +- **Secure Data Exchange:** Enable unidirectional or bidirectional secure data exchange between two users without the need for access to any form of centralized IT infrastructure. + +- **Data Integrity/Provenance:** Access activity logs provide transparency on data\'s integrity, ensuring your data has not been compromised or manipulated. + +- **Effective Incident Response:** In the event of a security incident, access governance facilitates effective incident responses with audit trails and access activity logs. + +- **Clear Accountability Structures:** Align access permissions with authenticated entities identities, ensuring individuals are accountable for actions within their scope. + +- **Adherence to Industry Regulations and Compliance:** Meet Zero Trust and other data acccess policy requirements, such as the DoD Zero Trust Strategy. + +- **Streamlined Access Management:** Automate and streamline access management processes, decreasing the burden on IT and ensuring efficient onboarding and offboarding processes. + +- **Cost Reduction through Automation:** Automating your data access governance accelerates workflows but also reduces operational costs associated with manual access management. + +# What does Aranya mean for me? + +Aranya is a software library that is deployed on an **endpoint** to securely manage data and access controls. Each endpoint can be a piece of hardware (e.g. spacecraft payload, drone, cellular device, etc.) or software (e.g. application). An **instance** is a single deployment of the Aranya software on a given endpoint, and each endpoint can have one or many instances deployed on it. + +An **entity,** which can also be referred to as a user, is used to identify an instance by assigning it a set of cryptographic keys used for identity, authorization, and authentication allowing it to govern the behavior of the endpoint. A **policy** is written to define these behaviors, accepted actions with corresponding commands, that will be generated. + +### Capabilities + +Aranya provides the following capabilities in a single, low size, weight, and power (SWAP) software platform, key to your organization\'s access governance: + +- **Identity & Access Management (IdAM)** + + - **RBAC (Roles):** Entities, or a group of entities, are given permission to interact with data or applications based on pre-defined roles. + + - **ABAC (Attributes):** Entities, or a group of entities, can be given permission to interact with data or applications based on dynamic attributes. + + - **Revocation:** Entities or whole RBAC/ABAC roles can be removed from access just as easily as it is to grant access. + +- **Decentralized Peer-to-Peer Messaging** + + - Enable secure data exchange between two endpoints without the need for access to any form of centralized IT infrastructure. + +- **Key Management** + + - Aranya leverages the crypto module that is implemented and configured on the endpoint to perform cryptographic functions used by policy commands. This means that an authority model can be designed to utilize the crypto module for generating, storing, and/or distributing cryptographic keys securely and in accordance with the governing policy, enabling dynamic key management. + +- **Data Segmentation** + + - Data can be segmented based on pre-defined roles or attributes through topic labels. For example, certain roles may be restricted from gaining access to a topic and other roles may be prerequisites for gaining access. In addition to roles, any attribute stored about the entity may be used to control access to a topic. + +- **Audit Log of Immutable Commands** + + - Using the Control Plane (described below), Aranya provides a high-assurance audit log of all commands, or instructions given by an entity to perform a specific task, providing data integrity and provenance for the movement of your data throughout your infrastructure. + + - The native data structure _is_ the audit log of all commands. The log, which is distributed and synchronized across all endpoints, provides a cryptographically authenticated, tamper-evident, high-assurance replication of all commands taken. + + - For each verified command, a cryptographic hash is created. If a previous event has been modified, the current one will no longer be valid due to the hash changing. + +# Aranya Platform + +## Deployment Ecosystem + +The Aranya platform is hardware and software agnostic and is designed to be built for a wide variety of platforms. Deployed as a library, the software makes no hardware or software assumptions. The software is serverless and asynchronous. The software is also link-agnostic, meaning it works with any transport protocol over trusted (single) or mixed (multiple) networks. + +**Designed for Embedded Device Support** + +- Lightweight platform: \<1.5 MB Binary and \<1.5 MB RAM + +- 100% built in Rust, a safety-first, high-level programming language + + - **Safety:** Rust's borrow checker ensures memory safety without the overhead of garbage collection. This means fewer memory leaks and crashes. + + - **Performance:** Comparable to C and C++, Rust provides fine-grained control of memory and other resources. + +**Supported Platforms** + +- Linux + +- ARM 32/64, x86 + +# Integration/API Overview + +Aranya provides additional utilities and APIs for ease of integration. These are all outlined below, though the API documentation for each can be found in separate documentation per request. + +## Aranya APIs + +### Configuration File API + +This API will load the configuration file and set up the environment using configured parameters. The configuration file provides information for all dependencies, to include encryption. + +### Initialization API + +This API provides the initialization of: + +1. Crypto Module + + - API provides a means to attach cryptographic modules into Aranya. For example, a FIPS-certified cryptographic module, or a hardware security or cryptographic acceleration module. + +2. Assignment of Crypto Keys to Entities + +3. Network transport + + - API provides a means to attach transport modalities to Aranya. + +### Access Control APIs + +Enables the functionality defined within the policy, allowing enforcement of identity management, roles and rules. This includes the APIs that relate to capabilities within the policy actions and commands. + +### Data Exchange APIs + +> **Off-Graph Data Exchange API** +> +> Provides an off-graph, real-time message-passing API with end-to-end encryption. +> +> **On-Graph Data Exchange API** +> +> Provides an on-graph message-passing API for guaranteed data delivery with end-to-end encryption. + +### Transport APIs + +Transport API uses the appropriate Aranya protocol to process communications between two endpoints. Endpoints must synchronize their state to allow peers to exchange commands and update the DAG, if on-graph data exchange API is called, with newly received commands. An entity must request their peer to sync by sending them a snapshot of their DAG, to which the peer responds with the set of commands that the entity is missing. If the peer suspects they are missing some commands which the peer entity has, they can issue a sync request in return. + +If the off-graph data exchange API is called, then Aranya will use the appropriate encryption/decryption keys to send and receive data between endpoints, leveraging the network protocol configured. + +# Glossary + +- **Action:** An action is a generated function defined in the policy language that can affect state. Actions create new commands to be evaluated by the policy and, if valid, added to the graph. Actions can be thought of as providing a contract (along with effects) to the application which is implemented by the policy. + +- **Attribute-based Access Control (ABAC):** A version of Identity Access Management that uses attributes over defined roles to grant an entity or group of entities\' permission(s) to interact with a graph. + +- **Audit and Monitoring**: A tool to review and monitor activities and detect suspicious behavior. + +- **Command:** Instruction given by an entity to perform a specific task. It is the object that is sent and stored to denote individual actions by different entities, as defined possible by the policy. For example, it could be to add an entity to a team, whereby the command object itself indicates the action that was performed and other necessary information, such as the credentials of the newly added entity. + +- **Directed Acyclic Graph (DAG):** A directed graph with no directed cycles. That is, a graph of vertices and edges, with each edge directed from one vertex to another, such that following those directions will never form a closed loop. + +- **Endpoint:** Where the Aranya software library is deployed. This can be a piece of hardware (e.g. spacecraft payload, drone, cellular device, etc.) or software (e.g. application). + +- **Entity:** Represents an instance and has an identity associated to it, as well as other crypto material which govern how it behaves on the endpoint. An entity could be used to describe a specific user on the platform. + +- **Graph**: Data structure of stored commands, where each command is connected by a line to the command that occurred immediately before it, as seen from the client\'s local state. + +- **IDAM**: (as defined by DOD): The combination of technical systems, policies and processes that create, define, and govern the utilization, and safeguarding of identity information. + +- **Instance:** Individual deployment of the Aranya library. A single endpoint can have one or many instances. + +- **Peer to Peer**: Allows computers to share access by acting as a server for each other. + +- **Policy**: A written document that defines all the permitted actions, commands, effects, validity checks, side-effects, facts, etc. Policies are customizable documents written in the domain specific language of the _Policy_ _Language_, + +- **Revocation**: Removal of access to a specific data set. + +- **Role-based Access Control (RBAC):** A version of Identity Access Management that uses roles to grant a user or group of users\' permission(s) to interact with a graph. + +- **Segmentation**: Chunking specific data as part of processes. + +- **Secure Authentication and Authorization:** Strong authentication methods and controls which limit access to authorized individuals. + +- **State:** All the information that defines how the software platform is currently functioning, how it can change, and how it should behave in different scenarios + +- **QUIC:** Quick UDP Internet Connections (QUIC) is a communication protocol built on top of the User Datagram Protocol (UDP) and uses encryption and multiplexing to make data transfer faster and more secure. + +- **UDP:** User Datagram Protocol (UDP) is a communication protocol that allows endpoints and applications to send data across a network without establishing a connection first. + +- **Zero-Trust:** A cybersecurity approach that requires all entities and devices to be authenticated and authorized before accessing data, endpoints, applications, and services. diff --git a/docs/tech-docs.md b/docs/tech-docs.md new file mode 100644 index 0000000..6a946c6 --- /dev/null +++ b/docs/tech-docs.md @@ -0,0 +1,398 @@ +**ARANYA TECHNICAL DOCUMENTATION** + +Table of Contents + +- [What is Aranya?](#what-is-aranya) + - [Terminology](#terminology) + - [Capabilities](#capabilities) +- [Aranya Architecture](#aranya-architecture) + - [Overview](#overview) + - [Control Plane vs. Data Plane](#control-plane-vs-data-plane) + - [Control Plane](#control-plane) + - [Data Plane](#data-plane) +- [Using Aranya](#using-aranya) + - [Decentralized Peer-to-Peer Data Exchange](#decentralized-peer-to-peer-data-exchange) + - [Data Segmentation](#data-segmentation) + - [Key Management](#key-management) +- [Quick Start Guide (Hello World Tutorial)](#quick-start-guide-hello-world-tutorial) +- [Appendix](#appendix) + - [Glossary](#glossary) + +# What is Aranya? + +Aranya is an **access governance and secure data exchange platform for organizations to control their critical data and services**. Access governance is a mechanism to define, enforce, and maintain the set of rules and procedures to secure your system's behaviors. Data governance is a more narrowed approach for applying the same mechanism to specifically address access permissions of all data in the system. + +Aranya ensures that your system's process for managing access controls to data or services is aligned with your organization's objectives and adheres to policy requirements. Defining the set of policies by specifying roles and permissions enables you to **safeguard sensitive information, maintain compliance, mitigate the risk of unauthorized data exposure, and grant appropriate access.** Aranya's decentralized platform allows you to define and enforce these sets of policies to secure and access your resources. + +This document will outline how Aranya delivers this functionality for policy-driven access controls and secure data exchange. + +### Terminology + +The following terms will be used throughout this document to describe Aranya deployments on **endpoints.** These deployments, or **instances,** are further defined as specific **entities,** or users, once the instance is assigned a specific set of cryptographic keys used for identity and authentication and are governed by written **policy**. + +**Endpoint:** A piece of hardware (e.g. spacecraft payload, drone, cellular device, etc.) or software (e.g. application) on which Aranya is integrated. + +**Instance:** A single deployment of the Aranya software. To note, each endpoint can have one or many instances deployed on it. + +**Entity:** You can think of this as a specific user identity and it is used to identify an instance by assigning it a set of cryptographic keys used for identity and authentication, allowing it to govern the behavior of the endpoint. + +**Policy:** Defines specific behaviors, or accepted actions with corresponding commands, that will be generated and executed on the endpoint. + +## Capabilities + +Aranya provides the following capabilities in a single, low size, weight, and power (SWAP) software platform, key to your organization's access governance: + +- **Identity & Access Management (IdAM)** + + - **RBAC (Roles):** Entities, or a group of entities, are given permission to interact with data or applications based on pre-defined roles. + + - **ABAC (Attributes):** Entities, or a group of entities, can be given permission to interact with data or applications based on dynamic attributes. + + - **Revocation:** Entities or whole RBAC/ABAC roles can be removed from access just as easily as it is to grant access. + +- **Decentralized Peer-to-Peer Messaging** + + - Enable secure data exchange between two endpoints without the need for access to any form of centralized IT infrastructure. + +- **Key Management** + + - Aranya leverages the crypto module that is implemented and configured on the endpoint to perform cryptographic functions used by policy commands. This means that an authority model can be designed to utilize the crypto module for generating, storing, and/or distributing cryptographic keys securely and in accordance with the governing policy, enabling dynamic key management. + +- **Data Segmentation** + + - Data can be segmented based on pre-defined roles or attributes through topic labels. For example, certain roles may be restricted from gaining access to a topic and other roles may be prerequisites for gaining access. In addition to roles, any attribute stored about the entity may be used to control access to a topic. + +- **Audit Log of Immutable Commands** + + - Using the DAG (described below), Aranya provides a high-assurance audit log of all commands, or instructions given by an entity to perform a specific task, providing data integrity and provenance for the movement of your data throughout your architecture. + + - The native data structure _is_ the audit log of all commands. The log, which is distributed and synchronized across all endpoints, provides a cryptographically authenticated, tamper-evident, high-assurance replication of all commands taken. + + - For each verified command, a cryptographic hash is created. As the keys are derived from the cryptographic cipher suite, if a previous event has been modified, the current one will no longer be valid. + +# Aranya Architecture + +As Aranya provides both access governance and secure data exchange, it analogously uses 2 familiar networking concepts, a **control plane** and **data plane**, to separate its core functionality between relevant components of the system. + +**Control Plane:** The Aranya control plane is the logical element of the system that handles administrative functionality needed to govern _access control operations defined in the policy_. It is used to manage and enforce the authority model by carrying out only operations that conform to the defined policy and validating them according to cryptographic credentials. For example, it will be the mechanism used to perform commands such as adding users or setting up a secure data exchange channel. + +**Data Plane:** Similarly, Aranya defines the data plane as what provides the primary function for the data to _securely exchange and encrypt that data end-to-end between two connected peer nodes_. The data plane is also subject to the permission system specified by the underlying policy; messages can only be sent/received by peers that have been given the appropriate credentials (e.g., cryptographic keys), which can typically require some set of permissions be explicitly granted first. + +For example, if an endpoint wants to send encrypted data to another endpoint, then the policy may require that the endpoints meet some conditions before it agrees to establish a secure communication channel between the endpoints or make the encryption/decryption key(s) available for them to use. For instance, it might require both users to be assigned to the same role or be associated to a common attribute. + +## Overview + +The components of Aranya come together to enable the control plane and data plane as needed, according to the underlying policy. For instance, the control plane needs a mechanism for tracking different access control operations so that it can determine how newly received operations should be executed. For this, Aranya includes a Directed Acyclic Graph (DAG) which stores policy commands at its nodes, in an immutable and verifiable format, and a Fact Database (FactDB) that keeps key-value pairs of information regarding the executed operations. These components make up the storage module that the control plane relies on for keeping track of previous executions, representing its current state, and assessing the authorization of new executions. + +To ensure that participating entities are acting over a common authoritative state, the control plane also utilizes the component of the system that performs graph synchronization of operational state, which is supplied through the sync transport API. + +Other core components of our system that enable the control plane and data plane functionalities are detailed below and can be seen in the foin Figure 1 below. + +A diagram of a software application Description automatically generated + +_Figure 1: System Architecture Overview Diagram_ + +**On-Graph Components:** + +- Pre-defined **policy** that contains the set of roles and permissions which make up the authority model. + +- **Crypto Module** that is used to perform all cryptographic functions without exposing sensitive material outside its domain. The system leverages a set of cryptographic protocols where the underlying algorithms are configurable up to NIST standard requirements for security. The system leverages whichever crypto is configured and does not provide the cryptographic cipher suite. + +- **Virtual Machine (VM) for executing the policy** and connecting it to the cryptographic module. + +- **Aranya Runtime** for orchestration of ordering, to route data and functionality between the necessary components for execution. + +- **Storage component (DAG and Fact DB)** to hold executed operations that have been validated and added to the audit log. + +- **Set of APIs for the client to perform or exchange policy operations.** + + - Generic Actions/Effects API + + - Sync Transport API + +**Off-Graph Components:** + +- High throughput, low latency **network channel for exchanging data between endpoints.** + +- **Shared Local Memory** to hold the **channel keys** for encrypting and/or decrypting data. + +- **Crypto Module** that is used to perform all cryptographic functions without exposing sensitive material outside its domain. + +- **Set of APIs to send and receive data** or **compute new channel keys.** + + - Channel Transport API + +_Note:_ The control plane and data plane may utilize different on or off-graph components to execute tasks they are responsible for. For example, while the data plane may mostly use the off-graph approach for handling secure message exchanges in real time, there may be scenarios where the message being sent must be captured by an immutable/verifiable command that is tracked against the authority state. This would grant usage of on-graph handling of messages by the data plane. + +**Runtime Client** + +The Runtime Client connects Aranya, your application, and all other external components together for passing data and commands. The application will perform its functional operation leveraging the Aranya APIs. The Aranya instance will route API calls to the Policy VM for execution, and any commands published by an action will be provided back to the Runtime Client for storage. If any effects are emitted by the commands, they too will be provided to the Runtime Client to be sent back to the user application via the APIs. + +The Runtime Client performs similar routing to handle peer-to-peer communication through the Sync API. + +## Control Plane vs. Data Plane + +The next two sections will lay out the foundational knowledge of the control plane and data plane which will be helpful to better understand how they interact within the system and the capabilities that each of them provides. + +### Control Plane + +The Aranya control plane is the heart of its access governance solution. It is where the defined policy is stored and executed to provide the functionality needed to enforce the set of roles, permissions, and requirements it outlines. The policy file is fully customizable to allow each organization to explicitly define the authority model that best suits their needs to control access to resources with as much granularity as they may need. + +The policy contains the full set of operations that users can perform in the system and specifies the permission requirements for each. These operations are denoted by data structures, known to Aranya as "Commands." Each command is essentially a piece of data that defines an operation and embeds into it the set of requirements needed to perform it. Hence, executing a command will carry out the operation it defines, and storing it will make up the audit log of authority model operations. + +The distributed data is stored as commands in a Directed Acyclic Graph (DAG) which is updated via a policy. The policy outlines the different commands, actions, and effects which define the objects, operations, and validity checks for those operations to update the state of the graph. + +All endpoints participating in the graph will receive all updates to the graph regardless of whether that command is relevant to that endpoint. This property allows commands to propagate asynchronously and opportunistically across the sync network to reach its intended destination through all available transport paths, but also imposes a cost in terms of network bandwidth and processing on each node for each command. Therefore, on-graph messages are limited to 100’s of messages per second, limited by available aggregate transport bandwidth and processing performance of the slowest endpoints on the DAG. + +**Workflow** + +The general workflow for exchanging control plane commands on-graph across two endpoints can be seen below in Figure 2. This workflow assumes a policy has been written and validated for all actions desired in the architecture. + +A diagram of a diagram Description automatically generated + +_Figure 2: General On-Graph Workflow_ + +**Directed Acyclic Graph (DAG)** + +The DAG is a decentralized record of all commands that are replicated and shared between endpoints over the peer-to-peer network managed by an entity's application on the endpoint. Aranya records each command using a DAG. We think about the graph in the way a tree grows - from the root to the tip of each branch - and how that tree grows over time to explain how a record of entity activity is created, and data is shared over time. Each time an entity operates on or shares new data, the historical record is changed. + +Since not all endpoints will always be in communication, these records and data storage are not linear. For instance, an endpoint may reset and will need to sync/integrate data with other entities. Hence, a new branch is created for operations performed by disconnected endpoints that are working in parallel and a sync between any two such endpoints will result in a new node on the graph that joins the two branches to represent a merged state. + +Aranya uses an ordering algorithm to produce a sequential ordering of commands. Conflict resolution becomes important for determining the order in which to execute commands received from syncing. Aranya uses its ordering algorithm on top of the policy to determine which command to prioritize to produce a linear sequence of commands. + +The algorithm is deterministic and can be somewhat compared to a consensus algorithm approach. It builds this linear sequence of commands from the DAG, but it does not change how data is represented in the DAG. The purpose of the linear sequence is to define an eventually consistent state across the system. Thus, the state of the system is denoted as the output of the ordering algorithm. + +**Policy** + +To execute actions, a custom policy file must be written and validated prior to deployment. Policies outline the accepted actions that can be issued and the corresponding commands that will be generated. Successful commands will emit effects and/or write facts (stored key value pairs) to the graph. The following is a basic overview of the parts that make up a policy. + +- **Action**: Actions are an application's entry point into the policy. They are functions that can perform entity checks and publish commands into the local database. When new commands arrive (from either local creation, or synced from other nodes), the policy for those commands is evaluated, which may produce fact changes and effects. Actions are, alongside effects, part of the application interface implemented by the policy. Actions execute atomically - they only succeed if all the commands they produce succeed. + +- **Command**: A command defines structured data, methods for packing and unpacking this data, and policy decisions for processing data. + +- **Effect**: Effects are structured data emitted by policy, which communicate changes and status from the policy to the application. The outcome of an effect is defined by policy. + +- **Fact**: A fact is a key value pair stored in the Fact Database. The shape of a fact is defined via policy with fact schema statements. + +To make changes to a graph, an entity calls an action to generate one or more commands. Another way to think about commands is to envision a piece of data (or fact) that you can manipulate by calling an action. The action is merely the "act" you wish to perform on the data and the command holds the actual execution of this action. Both actions and commands can be implemented on raw data if that data is passed to the action. For example, an action may be adding/removing entities, creating/deleting channels, or sending encrypted data. Once an action is called, the generated command is then evaluated by the policy engine to determine its validity given the current state and loaded policy. + +If a command is valid, it may be stored on the graph and some facts may be added, updated, or removed in the fact database. An effect, which provides information at the application level about the operation that was performed, can also be produced when a command is published. Upon syncing, all other peers may see the new validated command on the DAG. If they are authorized to view its contents, such as an encrypted message, then they will be able to obtain that too. + +**Fact Database** + +Information relevant to the system can be stored as a key/value pair, called a "fact." Facts are stored in the Fact Database and can only be created or mutated by a command. Executing a series of commands will produce a set of facts that depends on the order of execution, that is, if the commands are executed in a different order, they could result in a different set of facts. + +Policy evaluation in Aranya relies on the set of facts stored in the fact database to determine whether an operation defined by a command should be permitted to occur. If evaluation is successful, then the command gets fully executed and stored in the DAG. Otherwise, the command may be either rejected or recalled. Both an accepted and a recalled command can change or modify the fact database, however rejected commands never change facts. Rejected commands, therefore, are never added to the graph and are never executed. + +**Calling an Action** + +To call an Action, the entity will follow the following process: + +A diagram of a command Description automatically generated + +_Figure 3: Calling an Action Workflow_ + +**Syncing with a Peer (other entity)** + +To sync with a peer or other entity using Aranya, the entity will follow the following process: + +A diagram of a system Description automatically generated + +_Figure 4: Syncing with a Peer Workflow_ + +### Data Plane + +The control plane provides the full functionality to implement and enforce the authority model used to govern resource accesses, which includes the transmission of data representing the operations that users perform by utilizing the sync protocol. Since the sync protocol is designed to work with the DAG to keep a decentralized record of every command, it can have some overhead that increases the latency and may not be the most optimal choice for communicating data real time. + +As an alternative, Aranya's data plane may be selected to transmit data securely using end-to-end encryption that is bound to the specific entities as defined by the authority model of the policy in the control plane. An API is provided for this low latency, high throughput data (compared to on-graph) exchange by exposing lightweight channels to applications on the endpoints. + +Channels are governed by the authority model defined by the policy. Entities can be incorporated in as many channels as desired. Aranya manages cryptographic keys, leveraging the configured cipher suite for encrypting and decrypting messages on a per-channel basis. Aranya uses the crypto engine to negotiate keys while data is transmitted efficiently off-graph, i.e., without being stored in a command that is added to the DAG. Because the commands are not stored in the DAG, these channels are useful where large messages, network streams, or other high-throughput data must be sent to peers. + +Aranya will still leverage the DAG for managing the keys used for authentication. Data segmentation of channels is achieved using topic labels. Encryption is scoped to each channel, which supports one-to-one communication in either a unidirectional or bidirectional manner. The encryption/decryption algorithms provided by the crypto engine are symmetric and facilitate fast communication that is compatible with low resource environments such as embedded systems. + +**Workflow** + +**Creating a Channel** + +A channel is used to group together a fixed number of elements such as users, topics, and labels. User IDs identify the endpoints of the channel, and the topic label is an additional attribute available to write policies against. To create a channel, an entity will generate an ephemeral command. An ephemeral command is one that utilizes the same policy as all other commands, but which is never added to the DAG that audits them. Instead, entities transmit the command through an external transport mechanism. An ephemeral command is part of an ephemeral session, meaning it does not persist to the graph, but is still evaluated by the associated policy. The ephemeral command used as part of the setup includes the information required for the peers to set up the encryption keys that will be used for the channel. + +Once the command is validated, the crypto engine generates an encryption key associated with the entity and exposes it through shared memory. If the channel is specified as unidirectional, the entity creating the channel is only assigned an encryption key. If the channel is bidirectional, the entity will also be assigned a decryption key. Aranya stores the key(s) in its own database and associates the key or key pair with this specific channel for this specific entity. After the channel creator's keys have been assigned, a "create channel" command is sent to the specified receiver. Like the process for the initial sender entity, the command is processed by the receiver's associated policy and the crypto engine generates a decryption key (if unidirectional), or encryption/decryption keys (if bidirectional). After the sender and receiver have both processed the "create channel" command, they are free to send and receive messages over their new channel and no further messages will be processed by their policy. + +A diagram of a system Description automatically generated + +_Figure 5: Workflow when creating a Channel_ + +**Sending Data** + +To send data over the channel, an entity will prepare the bytes to submit to the API to be encrypted. Aranya will retrieve the encryption key associated with the intended channel and encrypt the message using the crypto engine. The user-defined transport method is then used to transmit the message to the receiver. Once the message has been received, Aranya will retrieve the entity's decryption key associated with this channel and use the crypto engine to decrypt the message. If a user's encryption or decryption key associated with the channel cannot be found, then the entity cannot encrypt or decrypt the message. + +While channels are one-to-one, a policy may define rules for an entity to send messages to multiple other entities over individual channels. This is facilitated by labels, which are defined in a policy and act on the permission system. A label is assigned to entities that want to communicate and a channel can only be created for entities assigned to that same label. Labels cannot be used to send a message to more than one entity as they are specifically used by policy to allow two entities to talk to each other using that label (if both points have that label assigned to them). + +A blue rectangular sign with white text Description automatically generated + +_Figure 6: Workflow to Send Data on a Channel_ + +# Using Aranya + +The Aranya Platform functionality includes a fully customizable authority model and secure data exchange that can be implemented to provide the security, accountability, efficiency, and resiliency organizations need to protect their most important resources within a decentralized, disrupted environment. Some of these uses include: + +1. **Decentralized Peer-to-Peer Data Exchange** + +2. **Data Segmentation** + +3. **Key Management** + +## Decentralized Peer-to-Peer Data Exchange + +Aranya provides interfaces for secure peer-to-peer data exchange, guaranteeing data delivery between endpoints, without the need for a centralized infrastructure governing your data. There are two ways data can be exchanged between endpoints: + +1. **Low-Throughput Broadcast (On-Graph):** Guaranteeing eventual delivery of your data to your endpoints through perpetuated syncing between peers to create a consistent end state. This broadcast can be one endpoint to one endpoint or one-to-many endpoints. + +2. **High-Throughput (Off-Graph):** Lowest latency, bulk encryption of your data through secure channels. + +Figure 7 below outlines the data flow between two endpoints, both with an Aranya instance and an application which will utilize the data. The two instances will leverage any transport that has been configured between the endpoints to exchange data via either the sync API (on-graph) or a high-throughput data exchange (off-graph), both defined below. + +A diagram of a data transfer Description automatically generated + +_Figure 7: Endpoint Integration Overview Diagram_ + +The attributes governing the use of on-graph and off-graph, and when each would be best to use, can be seen in Table 1 below. + + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeOn-GraphOff-Graph

Primary Use

+

(Core Functionality)

Control plane (Aranya commands)Data plane (data)

Secondary Use

+

(Other ways to use the core functionality in addition to main intention which may be advantageous for your use case)

Limited Data plane messages (commands with embedded data)Channel Control messages (ephemeral commands)
DistributionBroadcast across all sync connections (mesh and multi-hop support)Point-to-point (no multi-hop)
ThroughputLow throughput (100s of messages/sec depending on available transport and size of network)High throughput (limited by transport)
LatencyHigher latency due to overhead of graph operationsLow latency
DirectionUnidirectional (two unidirectional sync connections used to sync bi-directionally)Unidirectional

Message Encryption

+

(Application Layer)

Optional (note, transport layer may provide its own encryption, e.g. TLS for QUIC)Automatic
Resilience/RecoveryHighly resilientNo built-in recovery other than what is provided by underlying transport
AuthorizationAsymmetric keysSymmetric key
AuthenticationPer messagePer message
+ +_Table 1: Attributes of On-Graph vs. Off Graph Data Exchange_ + +## Data Segmentation + +Data segmentation is enabled through topic labels, segmenting the data based on specific topics governed by the same policy. As described in the previous section, channels created for off-graph messaging include a topic label in its definition. Channels are created using ephemeral commands which are evaluated by policy. Therefore, policies may be written that govern how topic labels are shared. For example, certain roles may be restricted from gaining access to a topic and other roles may be prerequisites for gaining access. In addition to roles, any attribute stored about the user may be used to control access to a topic. + +## Key Management + +Aranya leverages whichever crypto module is currently implemented and configured on the endpoint. Keys are then derived from the current authority model, defined over specific data channels. Data channels are a segmentation of entities that can exchange end-to-end encrypted data according to the authority model's pre-defined established permissions. Aranya's crypto engine generates an encryption key associated with the entity. If the channel is specified as unidirectional, the entity creating the channel is only assigned an encryption key. If the channel is bidirectional, the entity will also be assigned a decryption key. The key, or key pair, are stored locally in its own database and associates the key or key pair with this specific channel for this specific entity. After the channel creator's keys have been assigned, Aranya sends the "create channel" command to the specified receiver. Like the process for the initial entity, the command is processed by the receiver's associated policy and the crypto engine generates a decryption key (if unidirectional), or encryption/decryption keys (if bidirectional). + +Aranya also enables revocation. Specific entities, or whole RBAC/ABAC roles, can be removed from access to data as easily as it is to add them. In addition, revocation can be retroactive if needed, allowing the endpoint to remove a larger set of permissions as needed. + + +# Appendix + +## Glossary + +- **Action:** An action is a generated function defined in the policy language that can affect state. Actions create new commands to be evaluated by the policy and, if valid, added to the graph. When new commands arrive (from either local creation, or synced from other nodes), the policy for those commands is evaluated, which may produce fact changes and effects. Actions can be thought of as providing a contract (along with effects) to the application which is implemented by the policy. + +- **Attribute-based Access Control (ABAC):** A version of Identity Access Management that uses attributes over defined roles to grant an entity or group of entities' permission(s) to interact with a graph. + +- **Audit and Monitoring**: Regularly review and monitor activities and detect suspicious behavior. Use network monitoring tools to track access patterns and machine learning algorithms to detect anomalies. + +- **Channel:** A channel is a segmentation of entities that can exchange end-to-end encrypted data according to the authority model's pre-defined established permissions. + +- **Command:** Instruction given by an entity to perform a specific task. It is the object that is sent and stored to denote individual actions by different entities, as defined possible by the policy. For example, it could be to add an entity to a team, whereby the command object itself indicates the action that was performed and other necessary information, such as the credentials of the newly added entity. + +- **Directed Acyclic Graph (DAG):** A directed graph with no directed cycles. That is, a graph of vertices and edges, with each edge directed from one vertex to another, such that following those directions will never form a closed loop. + +- **Effect**: An Effect is a struct used in policy finish and recall blocks to describe the shape of side effects produced from processed commands. + +- **Endpoint:** Where the Aranya software library is deployed. This can be a piece of hardware (e.g. spacecraft payload, drone, cellular device, etc.) or software (e.g. application). + +- **Entity:** Represents an instance and has an identity associated to it, as well as other crypto material which govern how it behaves on the endpoint. An entity could be used to describe a specific user on the platform. + +- **Facts**: Key-value pair that is produced by evaluating a command. + +- **Graph**: Data structure of stored commands, where each command is connected by a line to the command that occurred immediately before it, as seen from the client's local state. + +- **IDAM**: (as defined by DOD): The combination of technical systems, policies and processes that create, define, and govern the utilization, and safeguarding of identity information. + +- **Instance:** Individual deployment of the Aranya library. A single endpoint can have one or many instances. + +- **Least Privilege Access:** This IDAM policy cornerstone gives users and systems only the minimal access needed to perform their tasks, reducing the risk of unauthorized access or activities. In satellite mesh networks, this could mean limiting certain ground stations' commands. + +- **Peer to Peer**: Allows computers to share access by acting as a server for each other. + +- **Policy**: A written document that defines all the permitted actions, commands, effects, validity checks, side-effects, facts, etc. Policies are customizable documents written in the domain specific language of the _Policy_ _Language_, + +- **Revocation**: Removal of access to a specific data set. + +- **Role-based Access Control (RBAC):** A version of Identity Access Management that uses roles to grant a user or group of users' permission(s) to interact with a graph. + +- **Segmentation**: Chunking specific data as part of processes. + +- **Segregation of Duties**: Responsibilities should be distributed among different individuals to prevent fraud or error. This is especially important in a satellite mesh network, where one error can have significant consequences. + +- **Secure Authentication and Authorization:** Implement strong authentication methods and control what authenticated users can do. Consider multi-factor authentication and digital certificates to ensure only authorized individuals have access. + +- **State:** All the information that defines how the software platform is currently functioning, how it can change, and how it should behave in different scenarios + +- **QUIC:** Quick UDP Internet Connections (QUIC) is a communication protocol built on top of the User Datagram Protocol (UDP) and uses encryption and multiplexing to make data transfer faster and more secure. + +- **UDP:** User Datagram Protocol (UDP) is a communication protocol that allows endpoints and applications to send data across a network without establishing a connection first. + +- **UDS:** Unix Domain Socket + +- **Zero-Trust:** A cybersecurity approach that requires all entities and devices to be authenticated and authorized before accessing data, endpoints, applications, and services. diff --git a/docs/walkthrough.md b/docs/walkthrough.md new file mode 100644 index 0000000..95f4290 --- /dev/null +++ b/docs/walkthrough.md @@ -0,0 +1,350 @@ +# Getting Started with Aranya + +Disclaimer: this document is a work in progress. The code given here is not part of any tests and may break often during the initial releases or be missing +the full sequences required to complete some actions. Code referencing the internals of the daemon is also incomplete and potentially outdated. Please reference the API for more complete information. + +In this document, we will walk through a scenario with five users initializing and running Aranya. The users will create a team using Aranya and send messages to each other using AFC. There are a few things to keep in mind: + +- Any policy actions are determined by the implemented policy. This walkthrough will use the default policy defined [here](/crates/aranya-daemon/src/policy.md). + +- Security tip: This walkthrough is intended as an example to be run on a single machine. As such, a single machine is used to build all key bundles and run all daemons under a single user's profile. In production, each Aranya user's key bundle should be created under separate Linux users on their respective machines and preferably all private keys should be stored in a protected partition, such as an HSM, for maximum security. This avoids a single access point for all Aranya user keys in case a machine is compromised. + +# Outline + +The walkthrough includes five users who will be referred to by their user role. The actions performed by each user are based on the permissions assigned to each role in the [default policy](/crates/aranya-daemon/src/policy.md). There will be five users, `Owner`, `Admin`, `Operator`, `Member A` and `Member B`. We will use the [`daemon`](/crates/aranya-daemon/src/daemon.rs) implementation for this example. + +Step 1. [Prepare the device environment](#prereqs) + +Step 2: [Configure](#daemon-config), [build](#daemon-build) and [run](#daemon-run) the daemon for each user + +Step 3. Submit an action to the `Owner`'s daemon to [create a team](#create-team) + +Step 4. Submit actions to [populate the team](#add-users-team) with the rest of the users + +Step 5. Submit an action to the `Admin`'s daemon to [create an AFC label](#create-afc-label) + +Step 6. Submit an action to the `Operator`'s daemon to [assign the AFC label](#assign-afc-label) to `Member A` and `Member B` + +Step 7. Submit an action to `Member A`'s daemon to [create an AFC channel](#create-afc-channel) + +Step 8. Call the AFC API from `Member A`'s daemon to [send a message](#send-afc-msg). Optionally, submit call the AFC API from `Member B`'s daemon to send a message back. + +# Prerequisites + +## Build Dependencies + +The following dependencies must be present on the device building Aranya: + +- [Rust](https://www.rust-lang.org/tools/install) + + +## Environment Variables + +As this walkthrough assumes a single user will be playing all roles, we will set some environment variables to simplify the daemon commands. The variables will refer to executables, configuration files, key bundle and networking information for each user. This also assumes that the daemons are being run from the top-level of the `daemon` repository and a directory to store data specific to each user has already been set up. + +``` +OWNER_DAEMON_CFG="owner/daemon_config.json" + +ADMIN_DAEMON_CFG="admin/daemon_config.json" +ADMIN_ADDR="0.0.0.0:8082" + +OPERATOR_DAEMON_CFG="operator/daemon_config.json" +OPERATOR_ADDR="0.0.0.0:8083" + +MEMBER_A_DAEMON_CFG="member_A/daemon_config.json" +MEMBER_A_ADDR="0.0.0.0:8084" + +MEMBER_B_DAEMON_CFG="member_B/daemon_config.json" +MEMBER_B_ADDR="0.0.0.0:8085" +``` + +Keep in mind, the address, i.e., `_ADDR`, value for each user should match the `sync_addr` value in that user's daemon configuration file. For example, the `ADMIN_ADDR` environment variable is set here to `0.0.0.0:8082`. This will also be the `sync_addr` value stored in `admin/daemon_config.json`. There are more details in the configuration file below. + +# Daemon + +## Configuration + +At runtime, the daemon takes in a configuration file with paths to key and graph storage, the policy file, and networking for syncing and off-graph messaging. A complete example of a daemon configuration file can be found [here](/crates/aranya-daemon/example.json). + +The first user, Owner, will have a daemon configuration as follows: + +```json +{ + // The daemon's name. + "name": "Owner", + + // The daemon's working directory. + // + // Must already exist. + "work_dir": "owner", + + // Used to receive API requests from the user library client. + "uds_api_path": "owner/owner_api.sock", + + // The path where the daemon should write its PID file. + "pid_file": "/var/run/owner.pid", + + // Aranya sync server address. + "sync_addr": "0.0.0.0:8081" +} +``` + +Create a configuration file for each user, changing the ports and other user-specific values for each user. Now that the daemons have been configured, we can build and run them! + +## Build + +To build the daemon, invoke `cargo build`: + +```shell +$ cargo build --bin daemon --release +``` + +Since we have separate configuration files for each user, we only need one build of the daemon. This step only needs to be performed once. + +## Run + +To start the daemon for the owner, we run the following: + +```shell +$ target/release/daemon --cfg $OWNER_DAEMON_CFG +``` + +Repeat this step for all users, substituting the associated configuration file for each user as set in the environment variables: + +```shell +$ target/release/daemon --cfg $ADMIN_DAEMON_CFG +$ target/release/daemon --cfg $OPERATOR_DAEMON_CFG +$ target/release/daemon --cfg $MEMBER_A_DAEMON_CFG +$ target/release/daemon --cfg $MEMBER_B_DAEMON_CFG +``` + +Internally, the daemon is instantiated by loading the specified configuration file. Once created, the daemon starts using its `run` method. + +```rust +let daemon = Daemon::load(config).await?; + +daemon.run().await +``` + +We will walk through the steps performed by the `run` method to set up Aranya and AFC next. + +# Aranya and AFC Initialization + +The `run` method will first create the necessary objects to interact with Aranya, including tools for storage, cryptography and syncing. The daemon's `setup_aranya` method uses these items to instantiate the Aranya client for submitting actions. Then, the daemon will call `setup_afc`, depending on the configured transport method, to set up the networking required to send messages to peers using AFC. We will walk through these setup methods in the following sections. + +## Setup Aranya + +Dependencies of Aranya include a crypto engine, policy engine, and storage provider. The `setup_aranya` method takes as input the instantiated crypto engine, keystore and the public portions of the user keys, which are the three asymmetric cryptographic keys: `IdentityKey`, `SigningKey`, and `EncryptionKey`. + +This input is then used to instantiate a policy engine and storage provider. + +```rust +use crypto::{ + default::{DefaultCipherSuite, DefaultEngine}, + keystore::fs_keystore::Store as KeyStore, +}; + +use runtime::{ + storage::linear::{ + libc::FileManager, LinearStorageProvider + }, + ClientState, +}; + +use crate::policies::base::vm_policy::PolicyEngine; + +const TEST_POLICY: &str = "/path/to/policy.md"; + +/// Creates the Aranya client and server. + +async fn setup_aranya( + &self, + eng: DefaultEngine, + store: KeyStore, + pk: &PublicKeys, +) -> Result<(Client, Server)> { + + let user_id = pk.ident_pk.id(); + + let aranya = ClientState::new( + PolicyEngine::new(TEST_POLICY, eng, store, user_id)?, + LinearStorageProvider::new( + FileManager::new(self.cfg.storage_path()) + .context("unable to create `FileManager`)?, + ), + ))); +} +``` + +**NB**: This is an abbreviated version of the daemon's `setup_aranya` method, see [here](https://github.com/aranya-project/aranya/blob/main/crates/aranya-daemon/src/daemon.rs#L141) for the current implementation details. + +The daemon receives actions from the user via the user client API. When the client makes a call in the client library, it +may invoke a command in the daemon using an internal API. + + +## Syncer + +Once the Aranya client has been created by `setup_aranya`, the `run` method will instantiate a `Syncer`. In the process of syncing, it will send a message, which holds some of the most recently seen state, to a peer. The `Syncer` uses its `sync` method which calls the Aranya client's `sync_peer` method to send this request. Upon receiving the request, the peer will compare these commands against their own version of state. If they have seen new commands, the peer will respond with this new state. The `Syncer` iterates over the list of peers and goes through this process at some configured interval. Meanwhile, the `Syncer` also listens for and responds to incoming sync requests. This is all done automatically by the daemon once a team ID has been configured. The full implementation of this struct can be found [here](https://github.com/aranya-project/aranya/blob/main/crates/aranya-daemon/src/sync.rs#L88). + +## Setup AFC + +Before the client library can send data, the router component uses AFC to encrypt the data with the encryption key for that data's label. On the other side of the channel, the peer's router receives the traffic on its external network socket and uses AFC to decrypt the data with the key corresponding to the data's label. The router component then forwards the data as plaintext to the user's application. + +Now that Aranya and AFC are running, the daemon is ready to submit actions! + +# Join a team + +All Aranya operations, except for syncing, require users to join a team first. There are two ways a user may join a team: creating a team or being added to one. We will walk through each of these, first creating the team and then adding users. + +## Create team + +To create a team, the first user submits a `create_team` action which will initialize a new graph for the team to operate on. This user is automatically assigned the `Owner` role as part of the command. + +Send a `create_team` action to the `Owner`'s daemon: + +```rust +let client = Client::connect(owner_sock_path)?; +let team_id = client.create_team()?; +``` + +This will cause `Owner`'s daemon application to invoke the following action: + +`aranya_client.create_team()` + +A `CreateTeam` command is submitted on behalf of the first user to the daemon to be processed by Aranya. If valid, the command will be added to the user's graph of commands (i.e., their DAG), as the first node (or root) of the graph, and returns to the user the team ID that uniquely identifies the team they created. Additionally, a fact will be stored that associates `Owner` in the new team with the `Owner` role. The team has now been created and other users can be added to it. + +**NB**: the team ID should be stored for use later in the walkthrough as it will be used for adding other users to the team and can be used to sync the graph. + +## Add users to team + +To be added to the team, a user first needs to send the public portion of their user keys, the user key bundle, to an existing user in the team. This key exchange is done outside of the daemon using something like `scp`. Further, the existing user must have permission to add a user to the team. Based on the implemented policy, all new users, except the `Owner`, are added to the team with the `Member` role. Only users with the `Owner` role or `Operator` role may add a new user to the team. To get the keybundle of the current user: + + +```rust +// Get the keybundle of the user that should be added as an admin: +let admin_kb = client.get_key_bundle()?; + +// Send the keybundle to the Owner +// ... +``` + +Let's assume `Owner` has received the second user's keys and can add them to the team and assign the `Admin` role. This involves two commands, `AddMember` and `AssignAdmin`. The first is published by the `add_member` action which adds the second user to the team and the second is published by the `assign_admin` action which assigns the `Admin` role. `Owner` will use the daemon's `add_admin` subcommand to submit these two commands: + +```rust +// Create an instance of a Team API to add the admin using +// the ID of the team. +let team = client.team(team_id); + +team.add_device_to_team(admin_kb)?; +team.assign_role(admin_device_id, Role::Admin)?; +``` + +If processed successfully, new `AddMember` and `AssignAdmin` commands will be added to the graph and associates Admin to the team and their role. + +**NB**: Remember that users must process commands locally before they can act upon them. Thus, `Admin` must sync with a peer to receive the commands `Owner` performed to onboard them onto the team before they can perform any commands themself. + +To enable syncing, `Owner` should supply `Admin` with the team ID that will allow them to sync. This happens outside of the daemon, using something like `ssh`. + +`Owner` can repeat these steps to add the rest of the users to the team. So, after receiving the key bundle from the third, fourth, and fifth user, the `Owner` will perform the following: + +```rust +team.add_device_to_team(operator_kb)?; +team.assign_role(operator_device_id, Role::Operator)?; +``` + +This subcommand will submit two actions, `add_member` and `assign_operator`. The first will add the user to the team as a `Member` and the second will assign them the `Operator` role. The last two users will only be added to the team as `Member`s. + +```rust +team.add_device_to_team(member_a_kb)?; +team.assign_role(member_a_device_id, Role::Member)?; + +team.add_device_to_team(member_b_kb)?; +team.assign_role(member_b_device_id, Role::Member)?; +``` + +If these actions are processed successfully, new commands exist on the graph that associate the team members with their newly assigned roles. Before the new team members can submit actions, they must retrieve the team ID (remember this happens externally) to sync state and receive the commands that have associated them with the team. Once associated with the team and assigned a role, the users can begin submitting actions! + +Finally, network identifiers need to be assigned for the members that will use AFC. The network identifers are used by AFC to properly translate between network names and users. + +```rust +let member_a_net_id = "127.0.0.1:8084"; +let member_b_net_id = "127.0.0.1:8085"; + +operator_client.assign_net_name(member_a_device_id, member_a_net_id)?; +operator_client.assign_net_name(member_b_device_id, member_b_net_id)?; +``` + +# Message sending + +Now that all users have been added to the team, they can begin sending encrypted messages to each other, facilitated by AFC. When using AFC, messages are not stored on the graph and are only one to one between two users. We will walk through how users can send messages using each of these methods. + +## Off-graph messaging + +AFC provides functionality for encrypted peer to peer messaging via channels. This section will walk through a bidirectional channel being set up between `Member A` and `Member B`. + +### Create an AFC label + +As mentioned, a channel label must be created so it can be associated with the users and channel. Based on the default policy, an `Admin` can create an AFC label. So, `Admin`, who was assigned the `Admin` role, will submit an action to the daemon to create the label. + +```rust +// Have admin create the label using the team instance +// from the admin_client.team(team_id) +let label_num = 1337; +team.create_label(label_num)?; +``` + +This is an Aranya command, so the daemon passes it into the policy to be processed. If it is successful, the label is stored as a fact on the graph. + +### Assign an AFC label + +Now that it exists, the label can be assigned to `Member A` and `Member B`. Based on the default policy, the `Operator` role can assign AFC labels. So, `Operator`, who was assigned the `Operator` role, will submit the action to assign the label. If processed successfully, the Aranya command for assigning an AFC label will create a fact that associates the label, the user's `user_id`, and a channel operation. Since this is a bidirectional channel, each user will be given the `ReadWrite` channel operation. + +```rust + +// Assign label_num (1337) to Member A and Member B using the operator's +// team instance. +team.assign_label(member_a_device_id, label_num)?; +team.assign_label(member_b_device_id, label_num)?; +``` + +Once these commands are submitted, they are processed by the policy. If found valid, `Member A` and `Member B` are now both assigned the same label with the ability to interact over a bidirectional channel. + +### Create AFC channel + +The action for creating an AFC channel, `create_bidi_channel`, is called within an Aranya session to produce the ephemeral command, `CreateBidiChannel`, which contains the AFC channel keys. + +Now, `Member A` or `Member B` could create an AFC channel. The action for creating an AFC channel, `create_bidi_channel`, is called within an Aranya session and produces an ephemeral command, `CreateBidiChannel` which contains the AFC channel keys. + +```rust +let channel_id = member_a_client.create_channel(team_id, member_b_net_id, label_num)?; +``` + +The client library and daemon will handle the required communication to transfer the ephemeral command to `Member B`. Once the command is received by the `Router` on `Member B`'s device it is then evaluated by the recipient's policy. If valid, the channel keys are stored in this user's shared memory database. At this point, the channel is created and can be used for messaging between `Member A` and `Member B`. + +### Send messages + +NOTE: Sending data over AFC has not been added yet. + +To send a message, `Member A` will call AFC's API, `send_data`, with the message data and the channel ID. + +```rust +// Sample data, can be any bytes +let data = vec![1, 1, 2, 3, 5]; +// Send the data to over the channel to member A. The client library handles +// the transport. +member_a_client.send_data(channel_id, data)?; +``` + +This AFC command will use the channel's encryption key to encrypt the message and attach headers related to the contents. `Member B` can now read the message! + +Since this channel is bidirectional, `Member B` may also send a message to `Member A`. In this case, `Member B` will submit a similar action with `Member A`'s `user_id`. + +```rust +// Sample data, can be any bytes +let data = vec![8, 13, 21, 34, 55]; +// Send the data to over the channel to member B. The client library handles +// the transport. +member_b_client.send_data(channel_id, data)?; +``` + +Great job, you've now successfully stood up Aranya daemons, created an Aranya team, and sent messages using AFC!