temper/laravel-dbmask

此包已弃用且不再维护。没有建议的替代包。

1.4.2 2023-06-19 09:45 UTC

README

一个用于白名单动态数据库掩码的 Laravel 包。

你有没有想过

"如何与公司内的开发人员和分析师共享我们的数据库,同时遵守GDPR等隐私法规?

这个包可能就是你要找的!

在一定程度上,数据库种子脚本可能会有所帮助。但有时候,对公司内许多角色来说,访问真实数据或数据库的最新副本可能是至关重要的,例如快速收集真实世界的统计数据或查找错误。

此包可以从MySQL源连接创建一个只读实时过滤器(通过视图掩码)和/或一个读写过滤副本(物化表)。

为了保持“默认隐私”,它通过白名单而不是黑名单来处理数据。您明确指定要逐字复制的列、要匿名化的列以及要完全排除的列(和行)。

免责声明:此包包含代码,设置不正确时可能会从您的数据库中删除重要数据。在使用之前,请务必自行验证和审核代码,并创建备份以确保生产环境的安全。

欢迎贡献。

重要限制

以下MySQL功能可能会引起问题

  • 虚拟或存储生成列在创建掩码视图时可能会泄露数据。如果这是一个问题,请使用物化选项。
  • 触发器 & UDFs当前不会从源模式传输到目标。
  • 视图将出现在目标上,但应依赖于底层表的掩码配置。

安装

添加仓库

{
    "repositories": [{
        "type": "vcs",
        "url": "https://github.com/TemperWorks/laravel-dbmask"
    }],
    "require": {
        "temperworks/laravel-dbmask": "dev-master",
    }
}

使用Composer更新

composer update temperworks/laravel-dbmask

发布示例配置

php artisan vendor:publish --tag=dbmask

测试

此包需要真实MySQL数据库进行测试。请确保您在测试时使用不包含任何重要数据的数据库。

phpunit.xml.dist 复制到 phpunit.xml,并更改DB连接变量。
之后,只需运行 ./vendor/bin/phpunit

用法

关于此包

以一个生产数据库为例,其中只有一个用户表

create table users
(
  id                  int(10) unsigned auto_increment primary key,
  email               varchar(255) not null,
  first_name          varchar(255) null,
  last_name           varchar(255) null,
  password            varchar(60) null,
  social_security_num varchar(20) null,
  birth_date          date null,
  favorite_drink      varchar(20) null
)

数据科学家可能需要此生产数据库的副本,并且他们可能对按年龄组计算的favorite_drink等聚合数据感兴趣。问题是,通过授予对生产数据库的访问权限,您也将授予他们对包含social_security_number和(散列的)password字符串的数据库列的访问权限。

这是不可取的,因为它增加了个人数据泄露的风险。

更好的解决方案是提供一个(或实时过滤器)掩码敏感字段,例如通过将值设置为null或用假数据替换值。

实时掩码视图 & 物化掩码表

配置

dbmask.php 配置指定以下配置键

类型 描述
表格 [] 包含表格及其列的数组。省略的表格将不会包含在加密数据库中。
表格过滤器 [] 要筛选的行
加密 数组 包含两个数据库连接名称:一个 source 和一个 target
实体化 数组 包含两个数据库连接名称:一个 source 和一个 target
auto_include_fks 布尔值 是否默认包含所有外键
auto_include_pks 布尔值 是否默认包含所有主键
auto_include_timestamps bool[] 是否默认包含时间戳,可选地包含列名数组
连接 字符串 使用哪个数据库连接,如果不是默认连接
mask_datasets [] 可用于随机加密的数据集

tables 数组包含所有列转换

'users' => [
    // id will be included by default if auto_include_pks is true
    'id',
    // MySQL functions can be used to mask data
    'email' => "concat(md5('id'),'@example.com')",
    // A non-associative array value will be included unmasked
    'birth_date',
    // Sets the column to null
    'first_name' => 'null'
    // Picks a stable, semi-random English last name from a dataset, 
    // using the last_name column as a hash seed
    'last_name' => DBMask::random('last_name', 'english_last_names'),
    // Uses the application key to replace the value with a new generated password hash
    // In this case, all users end up with their password set to the bcrypt hashed value of `secret`.
    'password' => DBMask::bcrypt('secret'),
]

运行转换

在发布和编辑配置后,在 MySQL 中创建所需的模式,编辑配置并运行

php artisan db:mask
and/or
php artisan db:materialize

筛选行

table_filters 数组可以包含排除特定行的规则

// exclude records of people born after 2000
'users' => 'birth_date < 2000-01-01',
// include the whole table as a valid view, but truncate to zero records
'audit_log' => 'false'

伪造数据提供者

可以定义自定义随机化集,例如使用 Faker

$faker = Faker\Factory::create('nl_NL');

'tables' => [
    'users' => [
        'social_security_num' => DBMask::random('social_security_num', 'ssn')
    ]
]

'mask_datasets' => [
    // generates a set of form-validatable social security numbers
    'ssn' => DBMask::generate(100, function() use ($faker) {
        return $faker->unique()->idNumber;
    }),
]

从源到目标传输视图

如果源模式上存在视图,这些视图也可以传输到加密/实体化目标。

例如,如果源有一个 users_view,它将首名和姓氏连接到全名,并公开 SSN,那么定义表的匿名化配置。包括视图名称,不需要任何列配置--它毕竟没有实际的列,它只是指向加密的用户表。

在启用实时加密匿名化选项时,这也适用。在这种情况下,源视图将传输到目标,在那里它叠加在加密视图之上。

'tables' => [
    'users' => [
        'first_name' => "'Jane'"
        'last_name' => "'Doe'"
        'social_security_num' => DBMask::random('social_security_num', 'ssn')
    ],
    
    'users_view' => [],
]

尽管可以使用伪造的种子数据,但仍有一些限制

  • 当集合的大小小于表记录数时,无法保证唯一性
  • 非常大的数据集在视图中会负面影响性能。