金融、保险、医疗和政务系统处理的敏感数据,往往不止姓名、地址和社会保障号码。保单号、会员 ID、病历号等行业标识同样可能指向具体个人,却未必能被通用规则准确识别。Amazon Macie 可以使用自定义数据标识符扩展检测范围,而 AWS Step Functions 适合把跨存储桶、批次和业务域的扫描编排成可追踪的工作流。
把行业标识变成可维护的检测规则
Macie 自定义数据标识符通常由正则表达式、关键词、忽略词以及最大匹配距离组成。正则表达式负责描述格式,关键词提供上下文,二者结合可以减少误报。
例如,某保险系统中的保单号格式为 POL- 加 10 位数字。可以这样实践,先通过 AWS CLI 创建标识符:
aws macie2 create-custom-data-identifier \
--name "InsurancePolicyNumber" \
--description "Policy number in the form POL-1234567890" \
--regex 'POL-[0-9]{10}' \
--keywords policy policy-number policy_number 保单号 \
--maximum-match-distance 50
命令会返回自定义数据标识符 ID。后续分类任务应引用这个 ID,而不是在每次扫描时重复维护正则表达式。
规则设计不能只看“能否匹配”。像十位数字、会员号缩写或日期格式这样的宽泛模式,很容易把订单号和日志字段误判为 PII。上线前应准备三类测试样本:确定包含敏感标识的正样本、格式相似但不敏感的负样本,以及缺少上下文关键词的边界样本。
用状态机编排大批量扫描
Macie 负责检查 S3 数据,Step Functions 负责拆分任务、调用分类作业、等待结果并处理失败。一个实用输入可以把每个业务域或存储桶组表示为独立任务:
{
"Jobs": [
{
"Name": "claims-pii-scan",
"CustomDataIdentifierIds": ["替换为自定义标识符ID"],
"SamplingPercentage": 100,
"S3JobDefinition": {
"BucketDefinitions": [
{
"AccountId": "123456789012",
"Buckets": ["example-claims-data"]
}
]
}
}
]
}
下面是一个可改造的 Amazon States Language 定义。它使用 Map 并行创建分类任务,并轮询每个任务的状态。运行前需要替换输入中的账户、存储桶和标识符 ID,同时确保状态机角色可以调用相应的 macie2 API。
{
"Comment": "Run and monitor Amazon Macie classification jobs",
"StartAt": "Scan jobs",
"States": {
"Scan jobs": {
"Type": "Map",
"ItemsPath": "$.Jobs",
"MaxConcurrency": 5,
"Iterator": {
"StartAt": "Create classification job",
"States": {
"Create classification job": {
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:macie2:createClassificationJob",
"Parameters": {
"ClientToken.$": "States.UUID()",
"JobType": "ONE_TIME",
"Name.$": "$.Name",
"CustomDataIdentifierIds.$": "$.CustomDataIdentifierIds",
"SamplingPercentage.$": "$.SamplingPercentage",
"S3JobDefinition.$": "$.S3JobDefinition"
},
"ResultPath": "$.CreatedJob",
"Next": "Wait before polling"
},
"Wait before polling": {
"Type": "Wait",
"Seconds": 60,
"Next": "Describe classification job"
},
"Describe classification job": {
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:macie2:describeClassificationJob",
"Parameters": {
"JobId.$": "$.CreatedJob.JobId"
},
"ResultPath": "$.JobDetails",
"Next": "Check job status"
},
"Check job status": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.JobDetails.JobStatus",
"StringEquals": "COMPLETE",
"Next": "Job complete"
},
{
"Variable": "$.JobDetails.JobStatus",
"StringEquals": "CANCELLED",
"Next": "Job failed"
}
],
"Default": "Wait before polling"
},
"Job complete": {
"Type": "Succeed"
},
"Job failed": {
"Type": "Fail",
"Error": "MacieClassificationJobCancelled"
}
}
},
"End": true
}
}
}
创建状态机时,可将定义放入 definition.json,然后执行:
aws stepfunctions create-state-machine \
--name macie-custom-pii-scan \
--role-arn arn:aws:iam::123456789012:role/MacieScanStateMachineRole \
--definition file://definition.json
如果扫描对象数量很大,可以降低 MaxConcurrency,按业务域错峰执行,或者使用 Distributed Map 处理存放在 S3 中的任务清单。并发越高不一定完成得越快,还会增加 API 限流、状态转换和扫描费用。
不要把“任务完成”当成治理完成
分类任务完成只表示扫描阶段结束。生产方案还需要处理 Macie findings:可以通过 EventBridge 接收发现事件,再交给 Lambda、SQS 或安全运营平台进行分级、去重和工单流转。严重发现应包含存储桶、对象、检测类型和规则版本,避免响应人员只能看到一个模糊告警。
还要明确几个边界:Macie 主要分析 S3 中受支持的对象;加密方式、压缩格式、对象权限和文件类型会影响可扫描性;采样扫描可以控制成本,但不能证明未抽中的对象不含 PII。对于合规盘点,采样适合规则校准,全量扫描更适合最终确认。
上线前检查清单
- 为每种自定义标识准备正样本、负样本和边界样本。
- 使用关键词和匹配距离约束宽泛正则表达式。
- 限制状态机角色只访问必要的 Macie API 和目标资源。
- 为创建任务、轮询任务和事件处理设置重试、超时与告警。
- 记录规则 ID、版本、负责人和适用业务域。
- 先在少量存储桶上评估误报率与费用,再扩大并发和扫描范围。
Macie 解决的是内容识别问题,Step Functions 解决的是规模化执行问题。把检测规则、编排状态和发现处理拆开管理,才能让自定义 PII 扫描从一次性检查变成可审计、可重复的治理流程。