Search documentation of ash

# View Source Encrypt Attributes

    Mix.install([{:ash, "~> 3.0"}, {:ash_cloak, "~> 0.1.0"}, {:cloak, "~> 1.1"}],
      consolidate_protocols: false
    )

    Application.put_env(:my_app, MyApp.Vault,
      ciphers: [
        default: {
          Cloak.Ciphers.AES.GCM,
          tag: "AES.GCM.V1",
          key: Base.decode64!("ETpvtowVAL7JmcxfqJ+XVQWzKrt1ynAkC0vT7AxfyNU="),
          iv_length: 12
        }
      ]
    )

    defmodule MyApp.Vault do
      use Cloak.Vault, otp_app: :my_app
    end

    MyApp.Vault.start_link()

## Introduction

When dealing with PII(Personally Identifiable Information) or other sensitive data, we often want to encrypt this data, and control access to the decrypted values.

To do this in `Ash`, we do that with `AshCloak`. See the getting started guide in `AshCloak` for installation instructions.

## Encrypting attributes

1. If you have not yet, follow the getting started guide for `AshCloak` and `Cloak`
2. Add the `AshCloak` extension to your resource
3. Configure the attributes that should be encrypted
4. Add any other additional desired configuration (provided by `AshCloak`)

## Examples

    defmodule User do
      use Ash.Resource,
        domain: Domain,
        data_layer: Ash.DataLayer.Ets,
        extensions: [AshCloak]

      cloak do
        vault MyApp.Vault
        attributes [:ssn]
      end

      attributes do
        uuid_primary_key :id
        attribute :ssn, :string, allow_nil?: false
      end

      actions do
        defaults [:read, create: [:ssn], update: [:ssn]]
      end
    end

    defmodule Domain do
      use Ash.Domain,
        validate_config_inclusion?: false

      resources do
        resource User do
          define(:create_user, action: :create, args: [:ssn])
          define(:update_user, action: :update, args: [:ssn])
          define(:list_users, action: :read)
        end
      end
    end

    {:module, Domain, <<70, 79, 82, 49, 0, 1, 255, ...>>,
     [
       Ash.Domain.Dsl.Resources.Resource,
       Ash.Domain.Dsl.Resources.Options,
       Ash.Domain.Dsl,
       %{opts: [], entities: [...]},
       Ash.Domain.Dsl,
       Ash.Domain.Dsl.Resources.Options,
       ...
     ]}

## Data is encrypted when modified and is not displayed when inspecting.

    user = Domain.create_user!("111-11-1111")

    #User<
      __meta__: #Ecto.Schema.Metadata<:loaded>,
      id: "bc5284fe-294a-485e-8585-06130a4bca4e",
      aggregates: %{},
      calculations: %{},
      ...
    >

    # AshCloak turned ssn into a calculation
    user.ssn

    #Ash.NotLoaded<:calculation, field: :ssn>

    # Load the value to decrypt it on-demand
    Ash.load!(user, :ssn).ssn

    "111-11-1111"

← Previous Page Authorize Access to Resources
Next Page → Prevent concurrent writes