20 stable releases

2.0.10 Sep 12, 2024
2.0.5 Aug 20, 2024
2.0.0 Jul 23, 2024
1.1.0 Jul 25, 2024
0.1.0 Sep 16, 2023

#838 in Cryptography

Download history 82/week @ 2024-06-30 303/week @ 2024-07-07 390/week @ 2024-07-14 353/week @ 2024-07-21 185/week @ 2024-07-28 570/week @ 2024-08-04 574/week @ 2024-08-11 397/week @ 2024-08-18 550/week @ 2024-08-25 398/week @ 2024-09-01 455/week @ 2024-09-08 137/week @ 2024-09-15 187/week @ 2024-09-22 39/week @ 2024-09-29 73/week @ 2024-10-06 63/week @ 2024-10-13

368 downloads per month

Apache-2.0

740KB
15K SLoC

Antimatter Rust Library

Antimatter is a data control plane. It lets you control your data regardless of where it's stored or what clients are accessing it.

Please take a look at the developer docs for more information


lib.rs:

Antimatter

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.

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:

export ANTIMATTER_API_KEY=<domain's API key>

Then you will need to include this crate in your Cargo.toml:

[dependencies]
antimatter = "0.1.13"

Finally, here is the bare bones example to encapsulate some data to a file and then open it:

use antimatter::{capsule::common::Column, capsule::common::RowReader, 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 api_key = "<your API key>".to_string();
    let mut session = Session::new(domain, api_key).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![
        RowReader {
            tags: vec![],
            cells: 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")
            ],
        },
        RowReader {
            tags: vec![],
            cells: 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 = Box::new(std::fs::File::open(path).expect("failed to open file"));
    let mut capsule = session.open(
        "data-reader",
        HashMap::new(),
        HashMap::new(),
        Box::leak(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!("");
    }
}

Dependencies

~45–61MB
~1M SLoC