Cloak Documentation

repository·master·Indexed 20 days ago

https://github.com/danielberkompas/cloak

An Elixir encryption library that simplifies secure data handling through Vaults, automatic IV management, and tagged ciphertexts for easy key rotation. It supports custom ciphers via the Cloak.Cipher behaviour and provides transparent Ecto field encryption through the cloak_ecto package.

Tokens
6.3K
Snippets
32
Records
40
Agent score
66%

What's inside Cloak

  1. How Cloak's core abstractions work

    master

    Cloak relies on three main architectural pillars:

    1. Vaults: These are modules you define in your application and add to your supervision tree. You can run multiple vaults simultaneously, which is useful for umbrella apps or multi-tenant environments.
    2. Random IVs: Cloak automatically generates unique Initialization Vectors (IVs) using :crypto.strong_rand_bytes and includes them in the ciphertext. This simplifies storage as you don't need to manage IVs separately.
    3. Tagged Ciphertext: Every ciphertext includes metadata about the algorithm and key used. This enables automatic selection of the correct decryption parameters and simplifies key rotation, as the system can distinguish between old and new ciphertexts.
  2. Encrypt and decrypt data with Cloak

    master

    Cloak provides encryption and decryption through a Vault module that you define in your application. The library uses tagged ciphertexts, meaning the ciphertext itself contains metadata about the algorithm and key used, allowing Cloak to automatically select the correct parameters for decryption.

    To use Cloak, you must first define a Vault module and add it to your supervision tree. Once configured, you can use encrypt/1 and decrypt/1 (or their bang versions encrypt!/1 and decrypt!/1) to process data.

    # Encrypting data
    {:ok, ciphertext} = MyApp.Vault.encrypt("plaintext")
    
    # Decrypting data
    MypApp.Vault.decrypt(ciphertext)
    # => {:ok, "plaintext"}
  3. Upgrade Cloak from 0.7.x to 0.8.x

    master

    Upgrading from version 0.7.x to 0.8.x introduces new features without breaking changes.

    Key improvements include:

    • mix cloak.migrate now supports binary primary keys by using a cursor to iterate through database tables instead of relying on min/max IDs.
    • Introduction of Cloak.CustomCursor for customizing the fields used for the cursor.

    Most users will not need to perform any manual migration steps after updating the dependency.

  4. Configure Cloak.Vault using environment variables

    master

    If you need to fetch keys from system environment variables (e.g., CLOAK_KEY), implement the init/1 callback in your Cloak.Vault module instead of using static configuration.

    defmodule MyApp.Vault do
      use Cloak.Vault, otp_app: :my_app
    
      @impl GenServer
      def init(config) do
        config =
          Keyword.put(config, :ciphers, [
            default: {
              Cloak.Ciphers.AES.GCM, 
              tag: "AES.GCM.V1", 
              key: decode_env!("CLOAK_KEY"),
              iv_length: 12
            }
          ])
    
        {:ok, config}
      end
    
      defp decode_env!(var) do
        var
        |> System.get_env()
        |> Base.decode64!()
      end
    end
  5. Upgrade Cloak from 0.6.x to 0.7.x

    master

    Upgrading to Cloak 0.7 involves several architectural changes: encryption is now managed through Cloak.Vault modules, ciphertext no longer contains a module_tag, Ecto types are now project-specific, and the :encryption_version field is deprecated.

    Follow these steps to upgrade:

    1. Update your dependency to ~> 0.7.0.
    2. Create a Cloak.Vault module to hold your cipher configurations.
    3. Define project-specific Ecto types (e.g., using Cloak.Fields.Binary).
    4. Migrate existing data using mix cloak.migrate to convert old ciphertext to the new format.
    5. Remove the :encryption_version field from your database and schemas.
    6. Remove any :retired ciphers from your vault configuration once migration is complete.
    # Update dependency
    {:cloak, "~> 0.7.0"}