Skip to content

第 7 章 · 安全与合规


7.1 安全设计原则

ADAP 的安全设计遵循以下核心原则:

  1. 最小权限原则:每个组件(Lambda、Glue Job、EMR、Agent)使用独立 IAM Role,仅授予完成本职工作所需的最小权限
  2. 纵深防御:认证、鉴权、网络隔离、数据加密多层防护,任一层失效不导致整体沦陷
  3. 密钥零暴露:数据库密码等敏感信息全程不出现在代码、日志或前端请求中
  4. 用户数据隔离:所有数据按用户 ID(Cognito sub)严格隔离,跨用户无法访问

7.2 用户认证

7.2.1 Amazon Cognito User Pool

ADAP 使用 Amazon Cognito User Pool(adap-users) 管理用户身份:

配置项
登录方式邮箱 + 密码(不支持用户名登录)
邮箱验证注册后自动发送验证邮件,强制验证
密码策略最少 8 位,含大写字母 + 小写字母 + 数字
认证协议SRP(Secure Remote Password),不传递明文密码
MFA当前关闭(原型阶段),可后续启用 TOTP
账号恢复仅邮箱方式找回
自注册允许用户自主注册
数据保护CDK destroy 时保留用户数据(RemovalPolicy=RETAIN)

7.2.2 Token 配置

Token 类型有效期说明
Access Token1 小时用于 API 调用鉴权
ID Token1 小时含用户属性(email、sub 等),前端使用
Refresh Token30 天用于无感刷新 Access/ID Token

7.2.3 前端认证流程

用户输入邮箱 + 密码

前端调用 Cognito SRP 认证(AWS Amplify SDK)

Cognito 返回 Access Token + ID Token + Refresh Token

Token 存储在内存(不存 localStorage,防 XSS)

每次 API 请求携带 Authorization: Bearer <AccessToken>

Token 过期 → 用 Refresh Token 静默刷新 → 失败则跳转登录页

7.3 API 鉴权

7.3.1 REST API:Cognito Authorizer

REST API Gateway 使用 Cognito Authorizer 验证每个请求的 JWT Token:

HTTP 请求
  Header: Authorization: Bearer <AccessToken>

API Gateway Cognito Authorizer

验证 Token 签名(Cognito JWKS 公钥)
验证 Token 未过期
验证 aud(Client ID 匹配)

通过 → 将 claims 注入 requestContext.authorizer.claims
失败 → 返回 401 Unauthorized

后端 Lambda 从 claims.sub 获取用户唯一标识(owner_id),用于数据隔离:

python
owner_id = event["requestContext"]["authorizer"]["claims"]["sub"]
# 查询时仅返回该 owner_id 的数据

7.3.2 WebSocket API:Lambda 自定义鉴权

WebSocket $connect 时使用 Lambda 自定义鉴权器(adap-ws-authorizer) 验证 Token:

鉴权流程

WebSocket 连接请求
  URL: wss://xxx.execute-api.../prod?token=<IDToken>

Lambda 鉴权器(adap-ws-authorizer)

1. 从 queryStringParameters.token 提取 JWT
2. 从 Cognito JWKS 端点获取公钥(缓存 1 小时)
3. 用 PyJWT 验证签名、过期时间、aud(Client ID)

通过 → 返回 Allow IAM Policy + principalId
失败 → 返回 Deny IAM Policy → 连接被拒绝

JWKS 缓存机制:Lambda 容器级别缓存 Cognito 公钥(TTL=1 小时),避免每次连接都请求 JWKS 端点,减少延迟。


7.4 用户数据隔离

7.4.1 项目级隔离

adap-projects DynamoDB 表使用 GSI(owner_id-created_at-index)实现用户隔离:

  • 每个项目写入时携带 owner_id(来自 Cognito sub)
  • 查询时强制带上 owner_id 过滤,用户只能看到自己的项目
  • 即使猜到其他用户的 project_id,API 也会返回 403(owner_id 不匹配)

7.4.2 数据源隔离

数据源(数据库连接信息)同样与 owner_id 绑定:

  • 下拉框只显示当前用户保存的数据源
  • 跨用户无法复用数据源配置

7.5 密钥与敏感信息管理

7.5.1 数据库密码:SSM Parameter Store

ADAP 全程不传递明文数据库密码,统一通过 AWS SSM Parameter Store(SecureString 类型) 管理:

存储格式

参数路径: /adap/datasource/{datasource_id}/password
类型: SecureString(KMS 加密)

前端交互

  • 新建数据源时,前端只填写 SSM Key 路径(如 /adap/mysql/password
  • 密码在前端环境中不存在,不会出现在网络请求、日志、浏览器缓存中

运行时取用

python
# Agent 运行时通过 IAM Role 权限动态获取
ssm = boto3.client("ssm", region_name=config.AWS_REGION)
password = ssm.get_parameter(
    Name=password_ssm_key,
    WithDecryption=True          # KMS 自动解密
)["Parameter"]["Value"]

IAM 限制

# 所有 Lambda/Agent/Glue Job 的 SSM 权限仅限 /adap/* 路径
Resource: arn:aws:ssm:{region}:{account}:parameter/adap/*
Action:   ssm:GetParameter, ssm:GetParameters

7.5.2 其他敏感配置

配置项存储位置说明
AgentCore Memory IDSSM /adap/memory_idChief Architect 跨会话记忆标识
Step Functions ARNSSM /adap/sfn/arn优先从环境变量读取,降级到 SSM
QuickSight 用户名环境变量 QS_USER注入到 AgentCore 容器
EMR Application IDDynamoDB adap-settings由用户在 SettingsPage 配置,加密存储

7.6 IAM 最小权限

7.6.1 ADAP-LambdaAgentRole(Lambda 执行角色)

权限资源范围用途
S3 读写arn:aws:s3:::adap-*读写数据湖和 Agent 状态
DynamoDB 读写arn:aws:dynamodb:...:table/adap-*项目、事件、WS 连接、HitL 表
DynamoDB Streamarn:aws:dynamodb:...:table/adap-*/stream/*ws-sender 读取变更流
SSM 读写arn:aws:ssm:...:parameter/adap/*读取/写入数据库密码
Bedrock 调用指定模型 ARN调用 Claude 系列模型
AgentCore 调用arn:aws:bedrock-agentcore:...:runtime/*调用 Agent Runtime
Step Functionsarn:aws:states:...:stateMachine:adap-*启动 / 查询 SFN 执行
CloudWatch Logs所有Lambda 基础执行权限
Glue(部分)arn:aws:glue:...:*/adap-*查询 Glue 表、Job 状态

7.6.2 ADAP-GlueServiceRole(Glue ETL 执行角色)

权限资源范围说明
S3 读写arn:aws:s3:::adap-prototype-*仅限数据湖 Bucket
SSM 读取arn:aws:ssm:...:parameter/adap/*读取数据库密码
Glue 基础权限AWSGlueServiceRole 托管策略CloudWatch Logs 等

⚠️ 不挂载 AmazonS3FullAccessAmazonAthenaFullAccess,避免权限过宽。

7.6.3 ADAP-AgentCore-Role(Bedrock Agent 执行角色)

权限资源范围说明
Bedrock 模型调用Claude Sonnet 4.6 / Opus 4仅授权指定模型
S3 读写数据湖 Bucket读写 Agent 状态、PRD、中间结果
Knowledge BaseBedrock KB ARNRAG 检索行业知识库
Step Functionsadap-* 状态机Agent 触发后续阶段

7.6.4 ADAP-EMR-JobRole(EMR Serverless 执行角色)

权限资源范围说明
S3 读写数据湖 BucketPySpark 读写 ODS/DWD/DWS/ADS
Glue Catalog所有 adap 数据库读取表 Schema,写入 Iceberg 元数据
CloudWatch Logs指定日志组EMR 作业日志

7.7 网络与传输安全

7.7.1 HTTPS 强制

  • REST API Gateway:默认 TLS 1.2+,不支持 HTTP 降级
  • WebSocket API:wss://(WebSocket Secure),不允许 ws://
  • CloudFront → S3:Origin Access Identity(OAI),S3 禁止直接公开访问

7.7.2 S3 数据湖安全配置

python
s3.Bucket(
    self, "DataLakeBucket",
    block_public_access=s3.BlockPublicAccess.BLOCK_ALL,  # 完全屏蔽公开访问
    encryption=s3.BucketEncryption.S3_MANAGED,           # SSE-S3 服务端加密
    enforce_ssl=True,                                      # 强制 HTTPS 访问
)

7.7.3 VPC 网络隔离(生产建议)

Glue ETL Job 在私有 VPC 内运行,通过 Glue Connection(VPC 模式)访问 MySQL/RDS:

  • Glue Worker 启动在与 RDS 同安全组的子网内
  • ensure_glue_connection Tool 自动创建 Glue VPC Connection(仅读取 VPC 配置,不修改安全组规则)
  • Agent Runtime(AgentCore)部署在 VPC 私有子网,可访问 RDS

7.8 数据合规

7.8.1 PII 数据治理

详见第 5 章 5.4 节,此处补充合规流程:

ODS 数据接入完成

Data Governance Agent 自动触发 PII 扫描

识别敏感字段(双重策略:字段名匹配 + 采样值正则验证)

HIGH / MEDIUM / LOW 三级分类

申请 Lake Formation 列级标签(SENSITIVITY 维度)

生成 GovernanceReport(保存 DynamoDB + S3)

结果在前端"合规报告" Tab 展示给用户

7.8.2 数据生命周期管理

S3 数据湖配置了生命周期规则(CDK 定义):

数据前缀保留周期说明
ods/90 天ODS 原始数据,超期自动删除
athena-results/30 天Athena 查询结果缓存
dwd/ dws/ ads/无限制(默认)分析层数据,手动管理

7.8.3 项目删除与数据清理

ADAP 提供两种项目删除模式,满足数据清理合规需求:

模式 A(仅删除元数据)

  • 删除 DynamoDB 中的项目记录和事件记录
  • AWS 资源(Glue Tables、S3 数据、Athena 历史)保留
  • 适合:快速删除,保留底层数据用于审计

模式 B(级联删除)

  • 删除 DynamoDB 记录
  • 删除 Glue Tables(四层数据库中的所有表)
  • 删除 S3 对应前缀下的所有数据文件
  • 适合:满足数据删除合规要求(如用户注销、GDPR 数据删除请求)

7.9 安全最佳实践建议

以下为生产环境部署建议(当前原型阶段部分未实施):

建议项优先级说明
启用 MFAP1Cognito TOTP 二次验证,保护管理员账号
限制自注册P1生产环境关闭 self_sign_up,改为管理员邀请制
WAF 接入P1在 CloudFront + API Gateway 前挂载 AWS WAF,防 SQL 注入 / DDoS
启用 CloudTrailP1记录所有 AWS API 调用,满足审计要求
KMS 自定义密钥P2将 S3 加密从 SSE-S3 升级为 SSE-KMS(自管密钥)
VPC EndpointP2S3/DynamoDB/SSM 走 VPC Endpoint,避免流量出公网
PII 字段脱敏P2DWD 层对 HIGH 级 PII 字段做哈希或掩码处理
Lake Formation 细粒度权限P3实施列级访问控制,限制不同角色对 PII 字段的查询权限(v3.0 规划)
定期轮换 SSM 密码P2配合 AWS Secrets Manager 实现自动轮换

本章参考来源:infra/cdk/auth_stack.py、iam_stack.py、api_stack.py、lambda_authorizer.py、s3_stack.py、agentcore_stack.py、agents/data_governance.py

Released under the MIT License.