{"id":9088,"date":"2022-07-07T09:01:53","date_gmt":"2022-07-07T08:01:53","guid":{"rendered":"https:\/\/blog.capdata.fr\/?p=9088"},"modified":"2022-07-07T09:01:53","modified_gmt":"2022-07-07T08:01:53","slug":"postgresql-anonymizer","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/","title":{"rendered":"PostgreSQL Anonymizer"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F9088&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F9088&#038;title=PostgreSQL%20Anonymizer\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PostgreSQL%20Anonymizer&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F9088\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>Dans un contexte o\u00f9 la s\u00e9curit\u00e9 est un enjeu majeur, l&#8217;anonymisation des donn\u00e9es est un moyen suppl\u00e9mentaire d&#8217;assurer la protection de celles-ci.<br \/>\nD\u00e9velopp\u00e9e par Dalibo, PostgreSQL anonymizer est une extension qui permet de masquer ou de remplacer les donn\u00e9es sensibles d&#8217;une base de donn\u00e9es postgres.<\/p>\n<p>L&#8217;extension a une approche d\u00e9clarative de l&#8217;anonymisation : on peut d\u00e9clarer les r\u00e8gles de masquage directement dans la d\u00e9finition des tables en utilisant le langage de cr\u00e9ation DDL habituel.<br \/>\nCet article a pour but de faire une d\u00e9monstration de l&#8217;installation et le l&#8217;utilisation de cette extension avec des cas d&#8217;exemples cr\u00e9\u00e9s pour l&#8217;occasion.<\/p>\n<p>L&#8217;installation de l&#8217;extension sur ubuntu \u00e9tant un peu particuli\u00e8re, pour ceux souhaitant l&#8217;installer sur d&#8217;autres syst\u00e8mes, je vous mets ici le lien vers une documentation permettant de le faire sans encombres.<\/p>\n<h3><strong>Etape 1 : Installer un Postgresql 13 :<\/strong><\/h3>\n<p>Pour commencer, on installe une instance PostgreSQL 13 sur notre machine ubuntu<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">root@sarah:~# sudo apt-get -y install postgresql-13\r\nReading package lists... Done\r\nBuilding dependency tree\r\nReading state information... Done\r\nThe following packages were automatically installed and are no longer required:\r\nlibfreetype6 postgresql-client-10 postgresql-client-12\r\nUse 'sudo apt autoremove' to remove them.\r\nThe following additional packages will be installed:\r\npostgresql-plpython3-13\r\nThe following packages will be upgraded:\r\npostgresql-13 postgresql-plpython3-13\r\n2 upgraded, 0 newly installed, 0 to remove and 23 not upgraded.\r\nNeed to get 15.0 MB of archives.\r\nAfter this operation, 24.6 kB of additional disk space will be used.\r\nGet:1 http:\/\/apt.postgresql.org\/pub\/repos\/apt bionic-pgdg\/main amd64 postgresql-                                                                                                                                                             plpython3-13 amd64 13.7-1.pgdg18.04+1 [105 kB]\r\nGet:2 http:\/\/apt.postgresql.org\/pub\/repos\/apt bionic-pgdg\/main amd64 postgresql-                                                                                                                                                             13 amd64 13.7-1.pgdg18.04+1 [14.9 MB]\r\nFetched 15.0 MB in 1s (17.2 MB\/s)\r\nPreconfiguring packages ...\r\n(Reading database ... 38668 files and directories currently installed.)\r\nPreparing to unpack ...\/postgresql-plpython3-13_13.7-1.pgdg18.04+1_amd64.deb ...\r\nUnpacking postgresql-plpython3-13 (13.7-1.pgdg18.04+1) over (13.6-1.pgdg18.04+1)                                                                                                                                                              ...\r\nPreparing to unpack ...\/postgresql-13_13.7-1.pgdg18.04+1_amd64.deb ...\r\nUnpacking postgresql-13 (13.7-1.pgdg18.04+1) over (13.6-1.pgdg18.04+1) ...\r\nSetting up postgresql-13 (13.7-1.pgdg18.04+1) ...\r\nSetting up postgresql-plpython3-13 (13.7-1.pgdg18.04+1) ...\r\nProcessing triggers for postgresql-common (238.pgdg18.04+1) ...\r\nBuilding PostgreSQL dictionaries from installed myspell\/hunspell packages...\r\nRemoving obsolete dictionary files:<\/pre>\n<p>Une fois l&#8217;instance install\u00e9e, on doit t\u00e9l\u00e9charger les outils de d\u00e9veloppement de postgreSQL afin d&#8217;\u00eatre en mesure de compiler.<\/p>\n<h3><strong>Etape 2 : T\u00e9l\u00e9charger les outils de dev de postgresql<\/strong><\/h3>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">root@sarah:~# sudo apt-get install postgresql-server-dev-13\r\nReading package lists... Done\r\nBuilding dependency tree\r\nReading state information... Done\r\n...\r\nSetting up postgresql-server-dev-13 (13.7-1.pgdg18.04+1) ...\r\nProcessing triggers for man-db (2.8.3-2ubuntu0.1) ...\r\nProcessing triggers for mime-support (3.60ubuntu1) ...\r\nProcessing triggers for ureadahead (0.100.0-21) ...\r\nProcessing triggers for install-info (6.5.0.dfsg.1-2) ...\r\nProcessing triggers for libc-bin (2.27-3ubuntu1.5) ...\r\nProcessing triggers for systemd (237-3ubuntu10.53) <\/pre>\n<p>Ces outils seront essentiels pour installer l&#8217;extension et pouvoir la faire fonctionner correctement. Il n&#8217;existe pas \u00e0 ce jour de version toute pr\u00eate pour Ubuntu.<\/p>\n<h3><strong>Etape 3 : T\u00e9l\u00e9charger les sources depuis le repo git<\/strong><\/h3>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">root@sarah:~# git clone https:\/\/gitlab.com\/dalibo\/postgresql_anonymizer\/-\/tree\/master\r\nCloning into 'master'...\r\nfatal: unable to update url base from redirection:\r\nasked for: https:\/\/gitlab.com\/dalibo\/postgresql_anonymizer\/-\/tree\/master\/info\/refs?service=git-upload-pack\r\nredirect: https:\/\/gitlab.com\/dalibo\/postgresql_anonymizer\/-\/tree\/master\r\nroot@sarah:~# git clone https:\/\/gitlab.com\/dalibo\/postgresql_anonymizer.git\r\nCloning into 'postgresql_anonymizer'...\r\nremote: Enumerating objects: 5145, done.\r\nremote: Counting objects: 100% (487\/487), done.\r\nremote: Compressing objects: 100% (271\/271), done.\r\nremote: Total 5145 (delta 327), reused 277 (delta 216), pack-reused 4658\r\nReceiving objects: 100% (5145\/5145), 25.71 MiB | 19.23 MiB\/s, done.\r\nResolving deltas: 100% (3304\/3304), done.<\/pre>\n<h3><strong>Etape 4 : Compiler les sources<\/strong><\/h3>\n<p>Une fois nos ressources t\u00e9l\u00e9charg\u00e9es, il faut les compiler pour \u00eatre en mesure de les utiliser.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">root@sarah:~\/postgresql_anonymizer# make extension PG_CONFIG=\/usr\/lib\/postgresql\/13\/bin\/pg_config\r\nmkdir -p anon\r\ncp anon.sql anon\/anon--1.1.0.sql\r\ncp data\/*.csv anon\/\r\ncp python\/populate.py anon\/\r\nroot@sarah:~\/postgresql_anonymizer# sudo make install PG_CONFIG=\/usr\/lib\/postgresql\/13\/bin\/pg_config\r\ncp anon.sql anon\/anon--1.1.0.sql\r\ncp data\/*.csv anon\/\r\ncp python\/populate.py anon\/\r\ngcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer -fPIC -Wno-unused-variable -I. -I.\/ -I\/usr\/include\/postgresql\/13\/server -I\/usr\/include\/postgresql\/internal  -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I\/usr\/include\/libxml2   -c -o anon.o anon.c\r\ngcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fno-omit-frame-pointer -fPIC -Wno-unused-variable anon.o -L\/usr\/lib\/x86_64-linux-gnu -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -L\/usr\/lib\/llvm-6.0\/lib  -Wl,--as-needed  -shared -o anon.so\r\n\/usr\/bin\/clang-6.0 -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -Wno-unused-command-line-argument -O2  -I. -I.\/ -I\/usr\/include\/postgresql\/13\/server -I\/usr\/include\/postgresql\/internal  -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I\/usr\/include\/libxml2  -flto=thin -emit-llvm -c -o anon.bc anon.c\r\n\/bin\/mkdir -p '\/usr\/share\/postgresql\/13\/extension'\r\n\/bin\/mkdir -p '\/usr\/share\/postgresql\/13\/extension\/anon'\r\n\/bin\/mkdir -p '\/usr\/lib\/postgresql\/13\/lib'\r\ninstall -d \/usr\/lib\/postgresql\/13\/bin\r\ninstall -m 0755 bin\/pg_dump_anon.sh \/usr\/lib\/postgresql\/13\/bin\r\n\/usr\/bin\/install -c -m 644 .\/\/anon.control '\/usr\/share\/postgresql\/13\/extension\/'\r\n\/usr\/bin\/install -c -m 644 .\/\/anon\/*  '\/usr\/share\/postgresql\/13\/extension\/anon\/'\r\n\/usr\/bin\/install -c -m 755  anon.so '\/usr\/lib\/postgresql\/13\/lib\/'\r\n\/bin\/mkdir -p '\/usr\/lib\/postgresql\/13\/lib\/bitcode\/anon'\r\n\/bin\/mkdir -p '\/usr\/lib\/postgresql\/13\/lib\/bitcode'\/anon\/\r\n\/usr\/bin\/install -c -m 644 anon.bc '\/usr\/lib\/postgresql\/13\/lib\/bitcode'\/anon\/.\/\r\ncd '\/usr\/lib\/postgresql\/13\/lib\/bitcode' &amp;amp;&amp;amp; \/usr\/lib\/llvm-6.0\/bin\/llvm-lto -thinlto -thinlto-action=thinlink -o anon.index.bc anon\/anon.bc<\/pre>\n<p>A pr\u00e9sent l&#8217;extension devrait \u00eatre utilisable si tout s&#8217;est bien pass\u00e9. Il ne nous reste plus qu&#8217;\u00e0 mettre en place notre environnement de test.<\/p>\n<h3>Etape 5 : On se connecte, on cr\u00e9e une database client, avec une table client et on <span style=\"font-size: 18.72px;\">ins\u00e8re<\/span> notre premier client dedans<\/h3>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">postgres@sarah:~$ psql\r\npsql (13.7 (Ubuntu 13.7-1.pgdg18.04+1))\r\nType &quot;help&quot; for help.\r\npostgres=# create database client;\r\nCREATE DATABASE\r\npostgres=# \\connect client\r\nYou are now connected to database &quot;client&quot; as user &quot;postgres&quot;.\r\nclient=# create table pizza_client (id integer, nom varchar(30), prenom varchar(30), numero varchar(20));\r\nCREATE TABLE\r\nclient=# insert into pizza_client values (1, 'CONNOR', 'Sarah', '0600000000');\r\nINSERT 0 1\r\nclient=# select * from pizza_client;\r\nid | nom | prenom | numero\r\n----+--------+--------+------------\r\n1 | CONNOR | Sarah | 0600000000\r\n(1 row)<\/pre>\n<h3>Etape 6 : Cr\u00e9er et charger l&#8217;extension dans notre base de donn\u00e9es<\/h3>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# ALTER DATABASE client SET session_preload_libraries = 'anon';\r\nALTER DATABASE\r\nclient=# CREATE EXTENSION anon CASCADE;\r\nCREATE EXTENSION\r\nclient=# SELECT anon.init();\r\nNOTICE:  The anon extension is already initialized.\r\ninit\r\n------\r\nt\r\n(1 row)<\/pre>\n<p>Voici notre extension install\u00e9e et pr\u00eate \u00e0 fonctionner.<br \/>\nIl y a trois grandes fonctionnalit\u00e9s \u00e0 connaitre dans PostgreSQL anonymizer : le masquage par destruction de donn\u00e9es, le masquage dynamique et le dump s\u00e9curis\u00e9.<br \/>\nLes trois fonctionnent avec les m\u00eames fonctions d&#8217;anonymisation, que vous pouvez retrouver list\u00e9es <a href=\"https:\/\/postgresql-anonymizer.readthedocs.io\/en\/stable\/masking_functions\/\">ici<\/a>.<\/p>\n<h2>Exemple 1 : Masquage par destruction de donn\u00e9es<\/h2>\n<p>Le premier exemple que nous allons aborder est le masquage par destruction de donn\u00e9es. C&#8217;est un masquage d\u00e9finitif et pour tout les utilisateurs. Il peut servir notamment quand vous faites des recopies de donn\u00e9es sensibles de prod vers la pr\u00e9prod par exemple, afin d&#8217;anonymiser les donn\u00e9es que vous recopiez.<br \/>\nPour se faire, il faut d\u00e9clarer pour chaque champ de la table qu&#8217;on souhaite anonymiser une r\u00e8gle que l&#8217;extension suivra pour modifier les donn\u00e9es contenues dans les colonnes.<br \/>\nSi nous reprenons notre exemple avec notre table pizza_client. On souhaiterait masquer les informations sensibles de nos donn\u00e9es : les noms et pr\u00e9noms de nos clients, et leurs num\u00e9ros de t\u00e9l\u00e9phone.<br \/>\nPour chacune des colonnes qu&#8217;on veut anonymiser on choisit une fonction correspondant \u00e0 la modification qu&#8217;on veut appliquer.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# SECURITY LABEL FOR anon ON COLUMN pizza_client.nom IS  'MASKED WITH FUNCTION anon.fake_last_name()';\r\nSECURITY LABEL\r\nclient=# SECURITY LABEL FOR anon ON COLUMN pizza_client.prenom IS 'MASKED WITH FUNCTION anon.fake_first_name()';\r\nSECURITY LABEL\r\nclient=# SECURITY LABEL FOR anon ON COLUMN pizza_client.numero IS 'MASKED WITH FUNCTION anon.random_phone()';\r\nSECURITY LABEL<\/pre>\n<p>Et une fois qu&#8217;on a d\u00e9finit toutes les r\u00e8gles de masquage que l&#8217;on d\u00e9sire, on a plus qu&#8217;\u00e0 utiliser la fonction anon.anonymize_database() pour les appliquer.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# SELECT anon.anonymize_database();\r\nanonymize_database\r\n--------------------\r\nt\r\n(1 row)\r\nclient=# select * from pizza_client;\r\nid | nom | prenom | numero\r\n----+----------+--------+------------\r\n1 | Prosacco | Karl | 0466543869\r\n(1 row)<\/pre>\n<p>On peut constater que les donn\u00e9es d&#8217;origine ont \u00e9t\u00e9 modifi\u00e9es au passage de la fonction. La modification est d\u00e9finitive, et on peut parfaitement envisager d&#8217;utiliser ces donn\u00e9es modifi\u00e9es comme jeu de test anonymis\u00e9.<\/p>\n<h2><strong>Exemple 2 : Le masquage dynamique<\/strong><\/h2>\n<p>Le principe du masquage dynamique est de d\u00e9finir un ou plusieurs utilisateurs qui n&#8217;auraient pas le droit de voir les donn\u00e9es comme elles sont dans la base de donn\u00e9es. Cette m\u00e9thode ne modifie rien, c&#8217;est simplement du masquage appliqu\u00e9 pour un profil en particulier.<br \/>\nRecr\u00e9ons notre exemple pr\u00e9c\u00e9dent pour tester ce principe de masquage dynamique<\/p>\n<p>On commence par cr\u00e9er notre table :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# drop table pizza_client;\r\nDROP TABLE\r\nclient=# create table pizza_client (id integer, nom varchar(30), prenom varchar(30), numero varchar(20));\r\nCREATE TABLE\r\nclient=# insert into pizza_client values (1, 'CONNOR', 'Sarah', '0600000000');\r\nINSERT 0 1<\/pre>\n<p>On applique ensuite la fonction permettant de d\u00e9marrer le masquage dynamique :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# SELECT anon.start_dynamic_masking();\r\nstart_dynamic_masking\r\n-----------------------\r\nt\r\n(1 row)<\/pre>\n<p>Ensuite, on cr\u00e9\u00e9 un nouveau r\u00f4le, le r\u00f4le pour qui les donn\u00e9es seront masqu\u00e9es et on lui applique le label masqu\u00e9 :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# CREATE ROLE capdata LOGIN;\r\nCREATE ROLE\r\nclient=# SECURITY LABEL FOR anon ON ROLE capdata IS 'MASKED';\r\nSECURITY LABEL<\/pre>\n<p>Et on applique ensuite les label de masquage sur les donn\u00e9es qu&#8217;on autorise pas l&#8217;utilisateur \u00e0 consulter :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# SECURITY LABEL FOR anon ON COLUMN pizza_client.nom IS  'MASKED WITH FUNCTION anon.fake_last_name()';\r\nSECURITY LABEL\r\nclient=# SECURITY LABEL FOR anon ON COLUMN pizza_client.numero IS 'MASKED WITH FUNCTION anon.partial(numero,2,$$******$$,2)';\r\nSECURITY LABEL<\/pre>\n<p>A pr\u00e9sent il ne nous reste plus qu&#8217;\u00e0 nous connecter avec l&#8217;utilisateur cr\u00e9\u00e9 pour le test, et \u00e0 faire un select sur notre table pour voir si la fonction de masquage dynamique a fonctionn\u00e9.<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">client=# \\c - capdata\r\nYou are now connected to database &quot;client&quot; as user &quot;capdata&quot;.\r\nclient=&amp;gt; select * from pizza_client\r\nclient-&amp;gt; ;\r\nid | nom | prenom |   numero\r\n----+-----+--------+------------\r\n1 | Rau | Sarah  | 06******00\r\n(1 row)<\/pre>\n<h2>Exemple 3 : Le Dump anonymis\u00e9<\/h2>\n<p>Cette option est la derni\u00e8re propos\u00e9e par l&#8217;extension.<br \/>\nElle fonctionne exactement pareil que le pg_dump, mais elle cr\u00e9\u00e9 des dumps anonymis\u00e9s selon les r\u00e8gles d\u00e9finies dans les diff\u00e9rentes tables comme vu pr\u00e9c\u00e9demment.<br \/>\nCependant, cette partie de l&#8217;extension est tr\u00e8s critiquable. Elle fonctionne correctement mais poss\u00e8de plusieurs inconv\u00e9nients :<br \/>\n&#8211; On ne peut exporter qu&#8217;en format plain, les autres formats ne fonctionnent pas.<br \/>\n&#8211; Si des ordres ddl ou dml sont pass\u00e9s pendant que le dump est en cours, alors le fichier de sauvegarde sera inconsistant.<\/p>\n<p>Pour faire fonctionner le dump anonymis\u00e9, il suffit d&#8217;utiliser le script pg_dump_anon.sh. Il s&#8217;utilise de la m\u00eame fa\u00e7on que le pg_dump, poss\u00e9dant les m\u00eames options :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">pg_dump_anon.sh --help\r\n\r\nUsage: pg_dump_anon.sh [OPTION]... [DBNAME]\r\n\r\nGeneral options:\r\n-f, --file=FILENAME output file\r\n--help display this message\r\n\r\nOptions controlling the output content:\r\n-n, --schema=PATTERN dump the specified schema(s) only\r\n-N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\r\n-t, --table=PATTERN dump the specified table(s) only\r\n-T, --exclude-table=PATTERN do NOT dump the specified table(s)\r\n--exclude-table-data=PATTERN do NOT dump data for the specified table(s)\r\n\r\nConnection options:\r\n-d, --dbname=DBNAME database to dump\r\n-h, --host=HOSTNAME database server host or socket directory\r\n-p, --port=PORT database server port number\r\n-U, --username=NAME connect as specified database user\r\n-w, --no-password never prompt for password\r\n-W, --password force password prompt (should happen automatically)\r\n\r\nIf no database name is supplied, then the PGDATABASE environment\r\nvariable value is used.<\/pre>\n<h3>Conclusion :<\/h3>\n<p>Dans le trousseau de s\u00e9curit\u00e9 de PostgreSQL, l&#8217;anonymisation des donn\u00e9es est un must-have pour les utilisateurs manipulant des donn\u00e9es sensibles dans des syst\u00e8mes prot\u00e9g\u00e9s.<\/p>\n<p>PostgreSQL Anonymizer est simple d&#8217;utilisation et pratique. Il n&#8217;entraine pas de grosses chutes de performances et il est utilisable de diff\u00e9rentes mani\u00e8res comme vu dans l&#8217;article.<\/p>\n<p>A ma connaissance il n&#8217;existe pas d&#8217;autres extension sur le march\u00e9 capable de r\u00e9aliser le m\u00eame travail que PostgreSQL anonymizer.<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F9088&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F9088&#038;title=PostgreSQL%20Anonymizer\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PostgreSQL%20Anonymizer&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F9088\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Dans un contexte o\u00f9 la s\u00e9curit\u00e9 est un enjeu majeur, l&#8217;anonymisation des donn\u00e9es est un moyen suppl\u00e9mentaire d&#8217;assurer la protection de celles-ci. D\u00e9velopp\u00e9e par Dalibo, PostgreSQL anonymizer est une extension qui permet de masquer ou de remplacer les donn\u00e9es sensibles&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":41,"featured_media":9122,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[266],"tags":[407],"class_list":["post-9088","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-postgresql","tag-anonymisation"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PostgreSQL Anonymizer - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL Anonymizer - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Dans un contexte o\u00f9 la s\u00e9curit\u00e9 est un enjeu majeur, l&#8217;anonymisation des donn\u00e9es est un moyen suppl\u00e9mentaire d&#8217;assurer la protection de celles-ci. D\u00e9velopp\u00e9e par Dalibo, PostgreSQL anonymizer est une extension qui permet de masquer ou de remplacer les donn\u00e9es sensibles&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-07T08:01:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2022\/07\/hacker-2883632_960_720.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Sarah FAVEERE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sarah FAVEERE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\"},\"author\":{\"name\":\"Sarah FAVEERE\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2\"},\"headline\":\"PostgreSQL Anonymizer\",\"datePublished\":\"2022-07-07T08:01:53+00:00\",\"dateModified\":\"2022-07-07T08:01:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\"},\"wordCount\":2148,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"anonymisation\"],\"articleSection\":[\"PostgreSQL\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\",\"name\":\"PostgreSQL Anonymizer - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2022-07-07T08:01:53+00:00\",\"dateModified\":\"2022-07-07T08:01:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL Anonymizer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2\",\"name\":\"Sarah FAVEERE\",\"sameAs\":[\"http:\/\/blog.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/sfaveere\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PostgreSQL Anonymizer - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/","og_locale":"fr_FR","og_type":"article","og_title":"PostgreSQL Anonymizer - Capdata TECH BLOG","og_description":"Dans un contexte o\u00f9 la s\u00e9curit\u00e9 est un enjeu majeur, l&#8217;anonymisation des donn\u00e9es est un moyen suppl\u00e9mentaire d&#8217;assurer la protection de celles-ci. D\u00e9velopp\u00e9e par Dalibo, PostgreSQL anonymizer est une extension qui permet de masquer ou de remplacer les donn\u00e9es sensibles&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2022-07-07T08:01:53+00:00","og_image":[{"width":960,"height":640,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2022\/07\/hacker-2883632_960_720.webp","type":"image\/webp"}],"author":"Sarah FAVEERE","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Sarah FAVEERE","Dur\u00e9e de lecture estim\u00e9e":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/"},"author":{"name":"Sarah FAVEERE","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2"},"headline":"PostgreSQL Anonymizer","datePublished":"2022-07-07T08:01:53+00:00","dateModified":"2022-07-07T08:01:53+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/"},"wordCount":2148,"commentCount":1,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["anonymisation"],"articleSection":["PostgreSQL"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/","url":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/","name":"PostgreSQL Anonymizer - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2022-07-07T08:01:53+00:00","dateModified":"2022-07-07T08:01:53+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-anonymizer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL Anonymizer"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2","name":"Sarah FAVEERE","sameAs":["http:\/\/blog.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/sfaveere\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/9088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=9088"}],"version-history":[{"count":27,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/9088\/revisions"}],"predecessor-version":[{"id":9119,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/9088\/revisions\/9119"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/9122"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=9088"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=9088"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=9088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}