在传统的软件开发(DevOps)领域,将安全(SecOps)左移(Shift Left)已是行业标准。然而,MLOps管道引入了独特的新挑战:数据隐私、模型投毒(Poisoning)、依赖性膨胀以及训练环境的瞬态漏洞。要建立一个真正健壮的MLOps系统,我们必须将SecOps检查点嵌入到持续集成、持续训练和持续部署(CI/CT/CD)的每一个阶段。
本文将聚焦两个最实用的SecOps集成点:依赖项漏洞扫描和模型完整性验证。
Contents
1. MLOps中的安全挑战
与传统代码库相比,ML项目通常依赖大量的第三方库(例如:TensorFlow, PyTorch, Pandas),这些库往往版本更新快,且可能包含已知的CVE(Common Vulnerabilities and Exposures)。此外,模型本身作为管道的输出,其完整性(是否被篡改)和来源(是否经过批准)也至关重要。
2. 核心实践:左移安全扫描
“左移”意味着在模型训练甚至代码合并之前,就对所有环境和依赖进行安全审查。
我们将使用开源的通用漏洞扫描工具 Trivy 来检查训练环境和代码依赖。Trivy 可以扫描操作系统包、语言依赖(如 Python requirements.txt)、配置文件以及容器镜像。
实践一:集成依赖和容器镜像扫描
我们将演示如何在基于GitHub Actions的CI/CT管道中集成Trivy,确保在任何训练任务启动之前,相关的依赖库是安全的。如果发现严重漏洞,管道应立即失败(Fail Fast)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 name: MLOps Security and Training
on:
push:
branches: [ main ]
jobs:
security_check_and_train:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
# 步骤 1: 安装并运行 Trivy
- name: Install and Run Trivy
uses: aquasecurity/trivy-action/setup@v0
with:
version: '0.50.0'
# 步骤 2: 扫描 Python 依赖 (requirements.txt)
- name: Scan Python Dependencies
uses: aquasecurity/trivy-action@master
with:
# 扫描文件系统中的依赖
scan-type: 'fs'
security-checks: 'vuln'
format: 'json'
output: 'trivy-dep-results.json'
target: './requirements.txt'
# 设置退出代码,如果发现高危漏洞则管道失败
exit-code: '1'
severity: 'CRITICAL,HIGH'
# 步骤 3: 扫描用于训练的 Docker 镜像 (假设已预构建)
# - name: Scan Training Docker Image
# uses: aquasecurity/trivy-action@master
# with:
# image-ref: 'my-org/ml-train-base:latest'
# scan-type: 'image'
# exit-code: '1'
# severity: 'CRITICAL'
# 如果安全检查通过,则继续执行训练步骤...
- name: Start Model Training
if: success()
run: |
echo "Security scan passed. Starting model training..."
# python train.py
通过将exit-code: ‘1’和severity: ‘CRITICAL,HIGH’结合使用,我们有效地阻止了带有已知高危漏洞的环境被用于生产模型。
3. 实践二:模型完整性验证(Artifact Integrity)
模型(Artifact)在从训练环境转移到模型仓库(Model Registry),再到生产环境的过程中,可能面临被恶意篡改的风险(例如,注入后门或模型投毒)。确保模型完整性的最简单且最强大的方法是使用加密哈希(如SHA-256)。
操作流程:
- 在训练完成后,立即计算模型文件的哈希值。
- 将模型文件及其哈希值一同存储在模型仓库中,并将哈希值记录在模型的元数据(Metadata)中。
- 在部署阶段,在加载模型之前,重新计算当前模型文件的哈希值,并与元数据中的原始哈希值进行比对。
以下是一个简单的Bash脚本示例,用于在管道中执行哈希生成和验证:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #!/bin/bash
MODEL_ARTIFACT="./artifacts/final_model.onnx"
HASH_FILE="./artifacts/final_model.onnx.sha256"
# --- 阶段 1: 训练完成后的哈希生成 ---
echo "--- Generating SHA-256 Hash for the trained model ---"
if [ -f "$MODEL_ARTIFACT" ]; then
# 使用 sha256sum 计算哈希,并只提取哈希值
MODEL_HASH=$(sha256sum "$MODEL_ARTIFACT" | awk '{print $1}')
echo "$MODEL_HASH" > "$HASH_FILE"
echo "Model hash generated: $MODEL_HASH"
else
echo "Error: Model artifact not found at $MODEL_ARTIFACT"
exit 1
fi
# --- 阶段 2: 部署前的哈希验证 ---
# (假设在部署环境重新加载了模型和哈希文件)
echo "--- Verifying Model Integrity before Deployment ---"
ORIGINAL_HASH=$(cat "$HASH_FILE")
CURRENT_HASH=$(sha256sum "$MODEL_ARTIFACT" | awk '{print $1}')
if [ "$ORIGINAL_HASH" == "$CURRENT_HASH" ]; then
echo "Verification successful. Model integrity is maintained. Safe to deploy."
# Proceed with deployment logic
else
echo "Verification failed! Artifact hash mismatch. Potential tampering detected."
# Halt deployment
exit 1
fi
总结
将SecOps嵌入MLOps管道并非一次性工作,而是一个持续改进的过程。通过在管道初期集成依赖扫描(如Trivy),并在模型生命周期的关键转移点(如模型注册和部署)执行严格的完整性验证,我们可以显著提高AI基础设施的安全性和可信赖性。这确保了我们交付的模型不仅性能优秀,而且是安全可靠的。
汤不热吧