cipherstash_client

Module zerokms

Expand description

The zerokms module provides a client for interacting with the ZeroKMS service.

ZeroKMS provides key management and encryption services using CipherStash’s “Vitur” protocol. This client provides a high-level interface for managing keys, granting access and encrypting/decrypting data.

§Key Heirarchy

§Workspaces, Datasets and Clients

ZeroKMS is built around the concept of Datasets and Clients that are encapsulated within a Workspace.

  • Workspaces are the top-level entity that encapsulates all Datasets and Clients.
  • Datasets represent a set of data that is encrypted under the same key heirarchy.
  • Clients are entities that can generate and retrieve keys for one or more datasets.

§Authentication

To use the ZeroKMS client, a valid access token is required. You don’t need to provide this directly: it is handled by the client using one of 2 methods:

  • Stash CLI: You can use the stash CLI to authenticate and store the access token
  • Client Access Key: You can provide a client access key to the client to authenticate

Stash CLI is best for local development and testing, while the client access key is best for production.

§ZeroKMS Client

The ZeroKMS client provides a high-level interface for managing Datasets and Clients in ZeroKMS. It does not provide methods to encrypt or decrypt data. For that, you need to use a ZeroKMSWithClientKey client.

The ZeroKMS client can perform the following operations:

  • Create a new Dataset
  • Grant and Revoke access to a Dataset for a client
  • List all Datasets in a Workspace
  • Enable and Disable a Dataset
  • Modify a Dataset’s name or description
  • Create a new Client for a Dataset
  • List all Clients in a Workspace
  • Revoke (Delete) a Client

§Example: Create a Dataset

use cipherstash_client::zerokms::Error;
use cipherstash_client::config::ZeroKMSConfig;

#[tokio::main]
async fn main() -> Result<(), Error> {
    let zerokms = ZeroKMSConfig::builder()
        .with_env()
        .build()
        .expect("failed to build config")
        .create_client();

    zerokms.create_dataset("my-dataset", "My dataset description").await?;

    Ok(())
}

§ZeroKMSWithClientKey Client

The ZeroKMSWithClientKey is the same as ZeroKMS but with the ability to encrypt and decrypt data. Use it only when you need to perform encryption and decryption operations. If your client only needs to manage Datasets and Clients, use the ZeroKMS client.

The ZeroKMSWithClientKey client can perform the following operations:

  • Encrypt one or many values
  • Decrypt one or many values
  • Save and Load a Dataset’s configuration

§Example: Encrypt and Decrypt

use cipherstash_client::zerokms::{ClientKey, EncryptPayload, Error};
use cipherstash_client::config::ZeroKMSConfig;

let zerokms = ZeroKMSConfig::builder()
  .with_env()
  .client_id("29f4c409-da51-496d-a1b8-cea9a9fd2660")
  .client_key("e27aaa358784340a822d692a99c12692cd0...")
  .build_with_client_key()
  .expect("failed to build config")
  .create_client();

let message = b"Hello, World!";
let payload = EncryptPayload::new(message);
let encrypted = zerokms.encrypt_single(payload, None).await?;
let result = zerokms.decrypt_single(encrypted).await?;
assert_eq!(message, result.as_slice());

See also ClientKey and EncryptPayload.

§Specifying Dataset ID

When a client has access only to one dataset, ZeroKMS will automatically use that dataset for encryption and decryption. However, when a client has access to multiple datasets, you need to specify the dataset ID.

use cipherstash_client::zerokms::{ClientKey, EncryptPayload, Error};
use cipherstash_client::config::ZeroKMSConfig;

use uuid::Uuid;
// Dataset ID for the dataset you want to use
let dataset_id: Uuid = "901C968B-9AA9-453D-B024-B26739E3AC88".parse().unwrap();
let message = b"Hello, World!";
let payload = EncryptPayload::new(message);
let encrypted = zerokms.encrypt_single(payload, Some(dataset_id)).await?;
let result = zerokms.decrypt_single(encrypted).await?;
assert_eq!(message, result.as_slice());

§Descriptors

ZeroKMSWithClientKey includes the concept of a “descriptor” which is a string that describes the data being encrypted. It provides a way to identify the data being encrypted and decrypted which can be used to ensure the data is being used correctly.

Descriptors are included in the “Authenticated Associated Data” (AAD) of the encryption and decryption operations. This means that the descriptor is included in the authentication tag and any tampering with the descriptor will cause the decryption to fail. Descriptors are also used by ZeroKMS to track the usage of keys and data.

§Using Descriptors

A common use for descriptors is to identify the data being encrypted like the table, column and row ID in a database.

let message = b"Kate Smith";
// Descriptor for record with ID 1 in the "users" table and "name" column
let payload = EncryptPayload::new_with_descriptor(message, "users/name/1");
let encrypted = zerokms.encrypt_single(payload, None).await?;
let result = zerokms.decrypt_single(encrypted).await?;

Modules§

Structs§

  • NOTE: Debug is safe to implement because [KeySet] is opaque.
  • Response message to a [CreateClientRequest].
  • Struct representing a dataset. This is the response to a [CreateDatasetRequest] and a in a vector in the response to a [ListDatasetRequest].
  • Response type for a [ListClientRequest].
  • Struct to manage the config for a given database. At connection time, the Driver will retrieve config from Vitur for the currently connected database
  • Represents an encrypted record for storage in the database. Implements serialization and deserialization so you can use it with any serde-compatible format however convenience methods are provided for CBOR, MessagePack, Hex, and Base85 encoding.
  • The requirements for generating a data key from Vitur.

Enums§

  • Struct representing the dataset ids associated with a client which could be a single dataset or multiple datasets.

Functions§

Type Aliases§