aws-samples/sample-guarded-user-controlled-attested-runtime-deployment
GitHub: aws-samples/sample-guarded-user-controlled-attested-runtime-deployment
基于 AWS Nitro TPM 证明的 LLM 安全推理平台,实现零操作员访问的跨账户模型权重保护。
Stars: 1 | Forks: 0
# Guardian 平台
_受保护的用户控制证明运行时部署与隔离访问 NitroTPM (Guardian Platform)_
使用 AWS Nitro TPM 证明和零操作员访问的 LLM 安全推理平台。这允许将模型安全地部署在模型消费者的 AWS 账户中,同时保护模型权重。此演示需要两个 AWS 账户来展示跨账户访问。这些账户不需要在同一个组织中。
此示例代码演示了 Guardian 平台的架构,仅供学习和原型设计之用,在任何生产部署之前应进行彻底的安全审查。
- **模型构建者账户**:下载模型,加密权重,构建容器镜像,将制品上传到 S3,构建 AMI,并与模型消费者账户共享。
- **模型消费者账户**:接收共享的 AMI 并启动 EC2 实例进行推理。
## 代码库
```
├── consumer/ # End-user application
│ ├── backend/ # Go API server (TPM attestation, model management)
│ └── frontend/ # React UI
├── controlplane/ # Admin WebSocket server for instance management
│ ├── backend/ # Go WebSocket server
│ └── frontend/ # React terminal UI
├── dockerbuilds/vllm/ # vLLM container with TPM support
└── imagebuild/zoa/ # KIWI-based AL2023 attestable AMI
```
## 前置条件
- 具有适当 IAM 权限的 AWS 账户
- Docker 和 Docker Compose
- Go 1.21+
- Node.js 20+
- NVIDIA GPU(用于 vLLM 推理)
- KIWI NG(用于构建 AMI)
## 基础设施设置
### 模型构建者账户 (`MODEL_BUILDER_ACCOUNTID`)
此账户托管:
- 用于模型加密的 KMS 密钥
- 用于存储加密模型权重的 S3 存储桶
- 用于存储容器镜像的 S3 存储桶
- AMI 构建基础设施
- 用于监控的 CloudWatch 日志组
### 模型消费者账户 (`MODEL_CONSUMER_ACCOUNTID`)
此账户托管:
- 运行可证明 AMI 的 EC2 实例
- 用于 TPM 证明和 KMS 访问的 IAM 角色
需要创建的资源:
1. 接受来自模型构建者账户的共享 AMI
2. 创建用于日志记录的 IAM 角色 `NitroTPM-Cloudwatch`
3. 创建具有 TPM 证明策略的 KMS 解密 IAM 角色
4. 启动启用了 Nitro TPM 的 EC2 实例
请注意,所有脚本均以 `-x` 启动,以便出于学习目的打印所有命令。
## 入门指南
### 1. 配置环境
复制并配置 `.env` 文件:
```
cd $HOME
cp .env.example .env
```
`.env` 中的必需变量:
- `ENCRYPT_KEY_ARN` - 用于模型加密/解密的 AWS KMS 密钥 ARN(暂时留空;在第 2 步之后使用 ModelBuilderStack CloudFormation 输出填充)
- `MODEL_BUILDER_ACCOUNTID` - 构建和加密模型的 AWS 账户 ID
- `MODEL_CONSUMER_ACCOUNTID` - 部署和使用模型的 AWS 账户 ID
### 2. 部署跨账户基础设施
在本地机器上,使用 AWS CLI 配置文件部署 CDK 堆栈:
```
cd infra
# ~300 秒
AWS_PROFILE=MY_CONSUMER_AWS_ACCOUNT_ID cdk deploy ModelConsumerStack ModelConsumerVpcStack
# ~800 秒
AWS_PROFILE=MY_BUILDER_AWS_ACCOUNT_ID cdk deploy ModelBuilderStack ModelBuilderVpcStack
```
### 模型构建者账户设置
本节中的所有剩余步骤均在模型构建者账户的 GuardianBuilder 实例上执行。使用 SSM 登录,克隆仓库,并配置 `.env` 文件(重复步骤 1)。可以在 ModelBuilderStack 的 CloudFormation 输出中找到 `ENCRYPT_KEY_ARN`。
### 3. 下载、加密并上传模型权重
从 Hugging Face 下载模型,使用 KMS 信封加密对权重进行加密,并上传到 S3。加密绑定到 KMS 密钥的证明策略,只有通过具有正确 PCR 值的 TPM 证明的实例才能在运行时解密这些权重。要使用不同的模型,请替换模型名称和 `--local-dir` 以使其匹配。
```
cd $(git rev-parse --show-toplevel)
cd dockerbuilds/vllm/
mkdir models
cd models/
# 如有需要,请选择不同的 model,但同时也要更新 --local-dir 以保持匹配
hf download ibm-granite/granite-4.0-h-1b --local-dir granite-4.0-h-1b --exclude ".*"
# 如果未找到:pip3 install huggingface_hub,或者尝试 ~/.local/bin/hf
cd ../
./upload-models.sh
```
### 4. 下载 AWS Nitro 根证书
后端应用需要 Nitro 根证书来验证 PCR 值是否已正确签名。从 [AWS 文档](https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html#validation-process)下载并将其放置在构建目录中:
```
cd $(git rev-parse --show-toplevel)
wget https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip -O /tmp/root.zip && unzip /tmp/root.zip -d /tmp/NitroCert
for dir in consumer/backend/aws_nitro_root.pem controlplane/backend/aws_nitro_root.pem; do cp -v /tmp/NitroCert/root.pem "$dir"; done
```
将 nitro-tpm-attest 二进制文件复制到容器镜像目录中,以便它可以在容器内运行:
```
cd $(git rev-parse --show-toplevel)
for dir in consumer/backend/nitro-tpm-attest controlplane/backend/nitro-tpm-attest dockerbuilds/vllm/nitro-tpm-attest; do cp -v /usr/bin/nitro-tpm-attest "$dir"; done
```
### 5. 构建容器镜像
构建容器镜像,使用 zstd 进行压缩,使用 KMS 加密,然后上传到 S3。容器镜像存储在 S3 中而不是容器注册表中,因为 AMI 在启动时使用 TPM 证明拉取并解密它们。
```
cd $(git rev-parse --show-toplevel)
docker compose build
cd imagebuild/
./upload.sh
```
### 6. 构建 AMI
使用 KIWI-ng 构建镜像并使用 coldsnap 将其作为快照上传,然后将其注册为 AMI。生成的 AMI 是不可变的——它使用 dm-verity 进行完整性验证,并使用 erofs 作为只读文件系统。构建过程会生成 PCR(平台配置寄存器)度量值,以唯一标识此 AMI 的启动链。
```
cd $(git rev-parse --show-toplevel)
cd imagebuild/
./build.sh
```
### 7. 使用 PCR 值更新 KMS 策略
每次 AMI 构建都会产生唯一的 PCR 值。PCR4 度量引导加载程序和内核,而 PCR7 捕获安全启动状态。这些值作为条件添加到 KMS 密钥策略中,确保只有启动此确切 AMI 的 EC2 实例才能解密模型权重和容器镜像。
在 AWS 控制台中,导航到 `ENCRYPT_KEY_ARN` 引用的 KMS 密钥,编辑密钥策略,并将 `TEMP_KEY_12345678910` 替换为构建输出中的 PCR4 和 PCR7 值:
```
cat /mnt/image/pcr_measurements.json
```
### 8. 与模型消费者账户共享 AMI
```
cd $(git rev-parse --show-toplevel)
. ./.env
aws ec2 modify-image-attribute \
--image-id ami-xxxxxxxxx \
--launch-permission "Add=[{UserId=$MODEL_CONSUMER_ACCOUNTID}]"
```
### 9. 启动控制平面
仍在 GuardianBuilder 实例上,启动控制平面:
```
cd $(git rev-parse --show-toplevel)
cd controlplane/
docker compose up -d
```
### 模型消费者账户设置
切换到模型消费者账户执行剩余步骤。
### 10. 为控制平面配置 DNS
消费者实例通过 WebSocket 连接回控制平面以进行管理和监控。在模型消费者账户的 Route 53 中,创建一个指向 GuardianBuilder 实例公网 IP 的 `controlplane.mymodel.any` A 记录。请参阅 [Route 53 文档](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html)。
### 11. 启动消费者实例
至少在 g5.8xlarge 上启动一个实例。有关安全组和子网的值,请参阅 ModelConsumerStack CloudFormation 堆栈输出。
```
aws ec2 run-instances \
--image-id "$AMI_ID" \
--instance-type g5.8xlarge \
--iam-instance-profile "Arn=arn:aws:iam::$MY_ACCOUNT:instance-profile/Guardian-Consumer" \
--security-group-ids "$SECURITY_GROUP_ID" \
--subnet-id "$SUBNET_ID" \
--metadata-options "InstanceMetadataTags=enabled" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ConsumerInstance},{Key=cross-account,Value=MODEL_BUILD_ACCOUNT_ID}]'
```
使用 EC2 Instance Connect 实时观看启动过程,或者在模型构建者账户中检查 `/aws/ec2/companyA` 下的 CloudWatch 日志。实例完成启动后,它将通过 TPM 进行证明,解密模型权重和容器镜像,并开始提供推理服务。消费者前端将可通过 `http://ConsumerInstance_IP:3001` 访问。
## 本地运行(可选)
用于在启用了 Nitro TPM 的 EC2 实例上进行开发和测试(不是本地笔记本电脑——TPM 证明需要 Nitro 硬件):
```
docker compose up --build
```
服务:
- 消费者前端: http://ConsumerInstance_IP:3001
- 消费者后端 API: http://ConsumerInstance_IP:8080
- vLLM: http://localhost:8000
- 控制平面前端: http://GuardianBuilderInstance_IP:3000
- 控制平面后端: https://GuardianBuilderInstance_IP:8090
## 核心功能
- **基于 TPM 的证明**:使用 AWS Nitro TPM 进行安全的模型解密
- **零操作员访问**:具有 dm-verity 和 erofs 的不可变 AMI
- **安全的模型加载**:将 KMS 与证明文档集成
- **实时监控**:Fluent Bit 日志输出至 CloudWatch
## 故障排除
请参阅 [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
标签:AWS Nitro, EVTX分析, Go语言, MITM代理, React, Syscalls, TPM可信度量, 可信执行环境, 大语言模型推理, 日志审计, 程序破解, 请求拦截, 零信任架构