Core Anonymizers
This page list all Anonymizers provided by DbToolsBundle.
EmailAnonymizer
EmailAnonymizer uses a hash function on the original value to make each unique email anonymization reproducible accross tables.
This Anonymizer will fill configured column with value looking like [username]@[domain.tld]
where:
[username]
is a md5 hash of the pre-anonymization value[domain.tld]
is the given domain option (orexample.com
by default)
For example contact@makina-corpus.com
will give 826464d916e6052ad209037ca71ce324@example.com
after anonymization.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 180, unique: true)]
#[Anonymize(type: 'email')]
private ?string $email = null;
// ...
}
# config/anonymization.yaml
customer:
email_address: email
#...
Or, with the domain option:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 180, unique: true)]
#[Anonymize(type: 'email', options: ['domain' => 'custom-domain.com'])]
private ?string $email = null;
// ...
}
# config/anonymization.yaml
customer:
email_address:
anonymizer: email
options: {domain: 'custom-domain.com'}
#...
INFO
Email value is salted prior to be hashed using md5 in order to prevent reverse hashing with rainbow tables. Salt is global across the same anonymization run, this means that the same email address anonymized twice will give the same value.
In order to disable the salt, set the use_salt
option to false.
WARNING
SQLite does implement MD5()
function, neither any hashing function: in order to get around this, the rowid
value is used instead which prevent email values anonymization from being reproducible across tables.
PasswordAnonymizer
This Anonymizer give you a way to set the same password for each one of your users. It is based on the Symfony PasswordHasher Component.
Options are :
algorithm
: algorithm to use to hash the plain password. (Default isauto
).password
: plain password that will be set for each row. (Default ispassword
)
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
/**
* @var string The hashed password
*/
#[ORM\Column]
#[Anonymize(type: 'password')]
private ?string $password = null;
// Or, with options:
/**
* @var string The hashed password
*/
#[ORM\Column]
#[Anonymize(type: 'password', options: ['algorithm' => 'sodium', 'password' => '123456789'])]
private ?string $password = null;
// ...
}
# config/anonymization.yaml
customer:
password: password
# Or, with options:
customer:
password:
anonymizer: password
options: {algorithm: 'sodium', password: '123456789'}
#...
IntegerAnonymizer
Anonymize integers by:
- randomly choosing an integer in a range delimited by 'min' and 'max' options
- altering the initial value by adding it a random value picked in a range computed from the 'delta' or 'percent' options
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column]
// Will fill the age column with a random integer
// in the [min, max] interval
#[Anonymize(type: 'integer', options: ['min' => 10, 'max' => 99])]
private ?int $age = null;
#[ORM\Column]
// Will add to each age value a random integer
// in the [-delta, +delta] interval
// In this example, an integer between -15 and 15 will be
// added to the initial value
#[Anonymize(type: 'integer', options: ['delta' => 15])]
private ?int $age = null;
#[ORM\Column]
// Will add to each age value a random percent
// of the initial value in the [-percent%, +percent%] interval
// In this example, a value between -10% and 10% of the initial value
// will be added to age.
#[Anonymize(type: 'integer', options: ['percent' => 10])]
private ?int $age = null;
// ...
}
# config/anonymization.yaml
customer:
age:
anonymizer: integer
options: {min: 10, max: 99}
customer:
# Will add to each age value a random integer
# in the [-delta, +delta] interval
# In this example, an integer between -15 and 15 will be
# added to the initial value
age:
anonymizer: integer
options: {delta: 15}
customer:
# Will add to each age value a random percent
# of the initial value in the [-percent%, +percent%] interval
# In this example, a value between -10% and 10% of the initial value
# will be added to age.
age:
anonymizer: integer
options: {percent: 10}
#...
FloatAnonymizer
Anonymize float by:
- randomly choosing an integer in a range delimited by
min
andmax
options - altering the initial value by adding it a random value picked in a range computed from the
delta
orpercent
options
You may also specify a precision
(default 2).
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column]
// Will fill the size column with a random float
// in the [min, max] interval.
#[Anonymize(type: 'float', options: ['min' => 10, 'max' => 99, 'precision' => 4])]
private ?float $size = null;
#[ORM\Column]
// Will add to each size value a random integer
// in the [-delta, +delta] interval.
// In this example, an integer between -15.5 and 15.5 will be
// added to the initial value.
#[Anonymize(type: 'float', options: ['delta' => 15.5, 'precision' => 4])]
private ?float $size = null;
#[ORM\Column]
// Will add to each size value a random percent
// of the initial value in the [-percent%, +percent%] interval.
// In this example, a value between -10% and 10% of the initial value
// will be added to the initial value.
#[Anonymize(type: 'float', options: ['min' => 10, 'max' => 99, 'precision' => 4])]
private ?float $size = null;
// ...
}
# config/anonymization.yaml
customer:
# Will fill the size column with a random float
# in the [min, max] interval.
size:
anonymizer: float
options: {min: 120, max: 300, precision: 4}
customer:
# Will add to each size value a random integer
# in the [-delta, +delta] interval.
# In this example, an integer between -15.5 and 15.5 will be
# added to the initial value.
size:
anonymizer: float
options: {delta: 15.5}
customer:
# Will add to each size value a random percent
# of the initial value in the [-percent%, +percent%] interval.
# In this example, a value between -10% and 10% of the initial value
# will be added to the initial value.
size:
anonymizer: float
options: {percent: 10}
#...
DateAnonymizer
Anonymize dates by either:
- randomly choosing an date or datetime in a given range delimited by
min
andmax
options, - altering the initial value by adding it a random value picked in a range computed from the
delta
options.
min
and max
options can be any string that can be parsed as a date by the DateTime
class constructor, for example:
- an absolute date:
2024-03-15
or datetime:2024-03-15 10:28:56
, - a relative time:
now +2 hours
,-3 month
, ...
delta
option can be either:
- an ISO interval specification, such as:
P1DT1M
(1 day and 1 minute), - a human readable date string that PHP can parse:
1 month -3 day +3 minutes
.
You can additionnally set the format
parameter:
date
will cast the generated date as a date without time,datetime
will generate a full timestamp.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column]
// Will add to the existing date a random interval
// in the [-delta, +delta] interval.
#[Anonymize(type: 'date', options: ['delta' => '1 month 15 day')]
private ?\DateTime $birthDate = null;
#[ORM\Column]
// Will pick a random date in the given
// in the [min, max] interval
#[Anonymize(type: 'date', options: ['min' => 'now -3 month', 'max' => 'now'])]
private ?\DateTimeImmutable $lastLogin = null;
#[ORM\Column]
// And example with absolute dates.
#[Anonymize(type: 'date', options: ['min' => '1789-05-05', 'max' => '2024-03-15', 'format' => 'date')]
private ?\DateTime $createdAt = null;
}
# config/anonymization.yaml
customer:
# Will add to the existing date a random interval in the [-delta, +delta] interval.
birthDate:
anonymizer: date
options: {delta: '1 month 15 day'}
customer:
# Will pick a random date in the given in the [min, max] interval.
lastLogin:
anonymizer: date
options: {min: 'now -3 month', max: 'now'}
customer:
# And example with absolute dates.
createdAt:
anonymizer: date
options: {min: '1789-05-05', max: '2024-03-15', format: 'date'}
#...
WARNING
Dates you give for min
and max
values will inherit from the PHP default configured timezone.
:::note When using a date range over 68 years, random granularity stops at the hour in order to avoid date add operation to be given an overflowing int value. :::
NullAnonymizer
Set all values to NULL
.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column]
#[Anonymize(type: 'null')]
private ?string $sensibleContent = null;
// ...
}
# config/anonymization.yaml
customer:
sensible_content: 'null'
#...
ConstantAnonymizer
Set all value to a constant value. Options are:
value
: the value you want to use to fill the columntype
: a SQL type for the given value (default value istext
)
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column]
#[Anonymize(type: 'constant', options: ['value' => '_______'])]
private ?string $sensibleContent = null;
#[ORM\Column]
#[Anonymize(type: 'constant', options: ['value' => '2012-12-21', 'type' => 'date'])]
private ?string $sensibleContent = null;
// ...
}
# config/anonymization.yaml
customer:
sensible_content:
type: constant
options: {value: '_______'}
customer:
sensible_content:
type: constant
options: {value: '2012-12-21', type: 'date'}
#...
Md5Anonymizer
This Anonymizer will fill configured column with a md5 hash of the pre-anonymization value.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 255)]
#[Anonymize(type: 'md5')]
private ?string $myDirtySecret = null;
// ...
}
# config/anonymization.yaml
customer:
my_dirty_secret: md5
#...
INFO
Hashing a string is not anonymizing it because hash functions have a reproducible output. In order to avoid decrypting data using rainbow tables, a salt will be added by default to string values prior to hashing.
Salt is global across the same anonymization run, which means that same values across the database will all inherit from the same hashed value, keeping things consistent.
In order to disable the salt usage, set the use_salt
option to false
.
WARNING
SQLite does implement MD5()
function, neither any hashing function, this anonymizer cannot be used with SQLite.
StringAnonymizer
This Anonymizer will fill configured column with a random value from a given sample.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 255)]
#[Anonymize(type: 'string', options: ['sample' => ['none', 'bad', 'good', 'expert']])]
private ?string $level = null;
// ...
}
# config/anonymization.yaml
customer:
level:
anonymizer: string
options: {sample: ['none', 'bad', 'good', 'expert']}
#...
TIP
If you use the same sample multiple times, if you use a large sample or if you use a generated one, it could be more efficient and convinient to create your own custom anonymizer, see the Custom Anonymizers section to learn how to do that.
LastnameAnonymizer
Works like the StringAnonymizer, but with a provided sample of 1000 worldwide lastnames.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 255)]
#[Anonymize('lastname')]
private ?string $lastname = null;
// ...
}
# config/anonymization.yaml
customer:
lastname: lastname
#...
FirstnameAnonymizer
Works like the StringAnonymizer, but with a provided sample of 1000 worldwide firstnames.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 255)]
#[Anonymize('firstname')]
private ?string $firstname = null;
// ...
}
# config/anonymization.yaml
customer:
firstname: firstname
#...
LoremIpsumAnonymizer
Replace a text with some lorem ipsum. Default behavior is to generate a single paragraph.
Available options:
paragraphs
: (int) number of paragraphs to generate,words
: (int) number of words to generate (could not be used in combination withparagraphs
option),html
: (bool) surround each paragraph with<p>
, default is false.sample_count
: (int) how many different values to use (default is 100).
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
class Customer
{
// ...
#[ORM\Column(length: 255)]
#[Anonymize('lorem')]
private ?string $message = null;
#[ORM\Column(length: 255)]
// Will generate 10 paragraphs, each one surrounded by a html `<p>` tag
#[Anonymize('lorem', ['paragraphs' => 10, 'html' => true])]
private ?string $message = null;
#[ORM\Column(length: 255)]
// Will only generate 5 words
#[Anonymize('lorem', ['words' => 5])]
private ?string $message = null;
// ...
}
# config/anonymization.yaml
customer:
message: lorem
customer:
# Will generate 10 paragraphs, each one surrounded by a html `<p>` tag
message:
anonymizer: lorem
options:
paragaphs: 10
html: true
customer:
# Will only generate 5 words
message:
anonymizer: lorem
options: {words: 5}
#...
AddressAnonymizer
This Anonymizer is multicolumn. It let you anonymize, at once, mutiple columns on one table that represent different parts of a postal address.
Each part will be fill with a coherent random address from a sample of 300 addresses around the world.
Available parts are :
Part | Definition | Example |
---|---|---|
country | The country | France |
locality | The locality in which the street address is, and which is in the region | Nantes |
region | The region in which the locality is, and which is in the country | Pays de la Loire |
postal_code | The postal code | 44000 |
street_address | The street address. For example, 5 rue de la Paix | 5 rue de la Paix |
secondary_address | Additional information (apartment, block) | Appartement 310 |
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use MakinaCorpus\DbToolsBundle\Attribute\Anonymize;
#[ORM\Entity()]
#[ORM\Table(name: 'customer')]
#[Anonymize(type: 'address', options: [
'street_address' => 'street',
'secondary_address': 'street_second_line'
'postal_code' => 'zip_code',
'locality' => 'city',
'region' => 'region'
'country' => 'country',
])]
class Customer
{
// ...
#[ORM\Column(length: 255)]
private ?string $street = null;
#[ORM\Column(length: 255)]
private ?string $streetSecondLine = null;
#[ORM\Column(length: 255)]
private ?string $zipCode = null;
#[ORM\Column(length: 255)]
private ?string $city = null;
#[ORM\Column(length: 255)]
private ?string $region = null;
#[ORM\Column(length: 255)]
private ?string $country = null;
// ...
}
# config/anonymization.yaml
customer:
address:
target: table
anonymizer: address
options:
street_address: 'street'
secondary_address: 'street_address_2'
postal_code: 'zip_code'
locality: 'city'
region: 'region'
country: 'country'
#...
TIP
Note that you don't have to provide a column for each part. You can use this Anonymizer to only anonymize some parts of an address. To do so, remove options you don't want in the example below.