View Source ecto_anon

Module Version Hex Docs Total Download License Last Updated

Simple way to handle data anonymization directly in your Ecto schemas


table-of-contents

Table of Contents

Installation

Add :ecto_anon to your mix.exs dependencies:

def deps do
  [
    {:ecto_anon, "~> 0.1.0"}
  ]
end

Usage

Define an anon_schema with all fields you want to be anonymized in your schema module

defmodule User do
  use Ecto.Schema
  use EctoAnon.Schema

  anon_schema [
    :email
  ]

  schema "users" do
    field :name, :string
    field :age, :integer
    field :email, :string
  end
end

Then use EctoAnon.run to apply anonymization on desired resource

user = Repo.get(User, id)
%User{name: "jane", age: 0, email: "jane@email.com"}

EctoAnon.run(user, Repo)
{:ok, %User{name: "jane", age: 0, email: "redacted"}}

schema

Schema

Declare an anon_schema with all fields you want to anonymize (regular fields, associations, embeds)

defmodule User do
  use Ecto.Schema
  use EctoAnon.Schema

  anon_schema [
    :email
  ]

  schema "users" do
    field :name, :string
    field :age, :integer
    field :email, :string

    anonymized()
  end
end

By adding a anonymized field in your migration, you can add anonymized() in your schema just like timestamps().

default-values

Default values

By default, a field will be anonymized with a default value based on its type

typevalue
integer0
float0.0
stringredacted
map%{}
decimalDecimal . new ( " 0.0 " )
date~D[ 1970-01-01 ]
datetime~U[ 1970-01-01 00:00:00Z ]
datetime_usec~U[ 1970-01-01 00:00:00.000000Z ]
naive_datetime~N[ 1970-01-01 00:00:00 ]
naive_datetime_usec~N[ 1970-01-01 00:00:00.000000 ]
time~T[ 00:00:00 ]
time_usec~T[ 00:00:00.000000 ]
booleanno change
idno change
binary_idno change
binaryno change

native-anonymization-functions

Native anonymization functions

anon_schema([
    email: :anonymized_email,
    birthdate: [:anonymized_date, options: [:only_year]]
])

Natively, ecto_anon embeds differents functions to suit your needs

functionroleoptions
:anonymized_dateAnonymizes partially or completely a date/datetime:only_year
:anonymized_emailAnonymizes partially or completely an email:partial
:anonymized_phoneAnonymizes a phone number (currently only FR)
:random_uuidReturns a random UUID

custom-functions

Custom functions

anon_schema([
    address: &__MODULE__.anonymized_address/3
])

def anonymized_address(:map, %{} = address, _opts \\ []) do
  address
  |> Map.drop(["street"])
end

You can also pass custom functions with the following signature: function(type, value, options)

migrations

Migrations

By importing EctoAnon.Migration in your ecto migration file, you can add an anonymized() macro that will generate an anonymized boolean field in your table:

defmodule MyApp.Repo.Migrations.CreateUser do
  use Ecto.Migration
  import EctoAnon.Migration

  def change do
    create table(:users) do
      add :firstname, :string
      add :lastname, :string
      timestamps()
      anonymized()
    end
  end
end

Combined with log option when executing the anonymization, it will allow you to identify anonymized rows and exclude them in your queries with EctoAnon.Query.not_anonymized/1.

options

Options

cascade

cascade

When set to true, allows ecto-anon to preload and anonymize all associations (and associations of these associations) automatically in cascade. Could be used to anonymize all data related a struct in a single call. Note that this won't traverse belongs_to associations.

Default: false

log

log

When set to true, it will set anonymized field when EctoAnon.run applies anonymization on a ressource.

Default: true

Copyright (c) 2022 CORUSCANT (Welcome to the Jungle) - https://www.welcometothejungle.com

This library is licensed under the MIT