1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! # Antimatter decentralized data control
//!
//! This crate provides a number of functions used to interact with Antimatter services and domains
//! hosted in it. For more information, go to [https://docs.antimatter.io](https://docs.antimatter.io/).
//!
//! ## The modules
//! This crate is split into 2 modules which are explained below.
//!
//! ### Session
//! This primarily focuses on establishing a connection to Antimatter's services, and performing API
//! requests to it in order to control your data. These include, but are not limited to:
//!
//! - Authentication and connection management.
//! - Encapsulation of data and related API calls to do so.
//! - Opening of encapsulated data and related API calls to do so.
//! - Data classification.
//! - Data access policy enforcement.
//!
//! ### Capsule
//! The primary focus here is on operation relating to encryption, decryption, storage, and
//! retrieval of data. Operations performed by this module occur on the host device. This module
//! contains:
//!
//! - The AEAD (Authenticated Encryption with Associated Data) logic.
//! - Capsule formats.
//! - Capsule bundling logic.
//! - Logic to read and write capsules from varying sources and destinations.
//!
//! ## Usage
//!
//! You will need a valid Antimatter domain with its API key in order to continue. First set the
//! API key for the valid Antimatter domain in your environment:
//!
//! ```bash
//! export ANTIMATTER_API_KEY=<domain's API key>
//! ```
//!
//! Then you will need to include this crate in your `Cargo.toml`:
//!
//! ```ignore
//! [dependencies]
//! antimatter = "0.1.13"
//! ```
//!
//! Finally, here is the bare bones example to encapsulate some data to a file and then open it:
//!
//! ```no_run
//! use antimatter::{capsule::common::Column, capsule::common::CellReader, session::session::{EncapsulateConfig, Session}};
//! use std::collections::HashMap;
//!
//! fn main() {
//!     // Create a Session object. This will use the provided domain ID
//!     // here and API key set in this environment.
//!     let domain = "<your domain ID here>".to_string();
//!     let mut session = Session::new(domain).unwrap();
//!
//!     // We generate configuration for encapsulating data with. At a minimum
//!     // we need to provide a valid write-context in the domain. We also
//!     // provide some extra information, but this is not required.
//!     let encapsulate_cfg = EncapsulateConfig {
//!         write_context_name: "data-writer".to_string(),
//!         extra: "Some extra information".to_string(),
//!         subdomain: None,
//!         subdomain_from: None,
//!         create_subdomains: None,
//!         async_seal: false,
//!     };
//!
//!     // Provide a file path to write and read from.
//!     let path = "/tmp/basic_capsule.amr.ca".to_string();
//!
//!     // We are going to encapsulate a table of data. In order to this we
//!     // first need to define the columns in the table. We do this by
//!     // providing a Vector of Column. In this example, we only give the
//!     // columns names.
//!     let column_defn = vec![
//!         Column {
//!             name: "col1".to_string(),
//!             tags: vec![],
//!             skip_classification: false,
//!         },
//!         Column {
//!             name: "col2".to_string(),
//!             tags: vec![],
//!             skip_classification: false,
//!         },
//!     ];
//!
//!     // We then define the table of data. This is a 2D Vector of bytes. We
//!     // lay out the table in a 2x2 grid and fill each element with bytes.
//!     //
//!     //  (r1, c1) | (r1, c2)
//!     //  ---------+---------
//!     //  (r2, c1) | (r2, c2)
//!     //
//!     let data_table = vec![
//!         vec![
//!             CellReader::new(
//!                 vec![],
//!                 std::io::Cursor::new(
//!                     "(r1, c1)".as_bytes().to_vec()),
//!                 ).expect("failed to create CellReader"),
//!             CellReader::new(
//!                 vec![],
//!                 std::io::Cursor::new(
//!                     "(r1, c2)".as_bytes().to_vec()),
//!                 ).expect("failed to create CellReader")
//!         ],
//!         vec![
//!             CellReader::new(
//!                 vec![],
//!                 std::io::Cursor::new(
//!                     "(r2, c1)".as_bytes().to_vec()),
//!                 ).expect("failed to create CellReader"),
//!             CellReader::new(
//!                 vec![],
//!                 std::io::Cursor::new(
//!                     "(r2, c2)".as_bytes().to_vec()),
//!                 ).expect("failed to create CellReader")
//!         ]
//!     ];
//!
//!     // Then encapsulate to file. This will handle all the necessary API
//!     // calls to Antimatter's services to encapsulate the table provided,
//!     // and if your write-context used includes classification hooks, these
//!     // will also be invoked and data in the provided table enriched with
//!     // tagging information.
//!     session.encapsulate_to_local_file(
//!         column_defn,
//!         data_table,
//!         vec![],
//!         encapsulate_cfg,
//!         path.clone(),
//!     )
//!     .expect("failed to encapsulate");
//!
//!     // We then immediately open the file and read it with the provided
//!     // read-context. Any policies attached to the read-context will be
//!     // enforced, and data redacted, as part of the reading process.
//!     let mut file = std::fs::File::open(path).expect("failed to open file");
//!     let mut capsule = session.open(
//!         "data-reader",
//!         HashMap::new(),
//!         HashMap::new(),
//!         &mut file,
//!     )
//!     .unwrap();
//!
//!     let (_span_tags, data) = capsule
//!         .read_all(&vec![])
//!         .expect("failed to read from capsule");
//!
//!     // Finally we print out the read data.
//!     for row in data {
//!         for col in row {
//!             print!("{} ", String::from_utf8(col).unwrap());
//!         }
//!         println!("");
//!     }
//! }
//! ```

pub mod capsule;
mod opawasm;
pub mod session;