KatsaounisThanasis/policy-as-code-ai
GitHub: KatsaounisThanasis/policy-as-code-ai
一个本地优先的 Policy-as-Code 工具,结合 OPA 策略扫描与本地 LLM 来自动解释风险、确定性修复 Terraform 配置并验证违规归零。
Stars: 1 | Forks: 0
# 🛡️ Policy-as-Code + AI 漂移解释器




[](https://github.com/KatsaounisThanasis/policy-as-code-ai/actions/workflows/policy-scan.yml)


**60秒体验:** `make scan` 发现配置错误,`make explain` 通过本地 LLM 告诉你每个错误的风险原因,`make remediate` 编写修复方案,而 `make verify` 会重新运行检测关卡以证明配置已清理干净。所有数据都不会离开你的机器。
## 问题所在
安全扫描器(Checkov, tfsec, OPA, KICS)擅长告诉你 Infrastructure-as-Code 哪里有问题,但在这之后就没多大帮助了。一次典型的运行会将 200 个发现结果倾倒到积压工作中。安全工程师提交一个工单。几周后,基础设施工程师可能会修复它。与此同时,配置错误已经被部署到了生产环境。
两个鸿沟依然存在:
1. **理解。** 像这样的发现结果 `AZ-STORAGE-003: public_network_access_enabled` 对匆忙中的开发者来说毫无意义。它为什么重要?影响范围(blast radius)有多大?
2. **行动。** 即使修复方案很明显,仍然需要有人去编写它并证明它确实消除了该发现结果。
## 它的作用
一个将原始策略违规转化为经过验证的修复方案的闭环:
```
terraform plan ─▶ OPA/Rego scan ─▶ AI explains each violation ─▶ deterministic fix ─▶ re-scan proves 0 violations
```
- OPA/Rego 评估 Terraform 计划并输出结构化的违规项。
- 本地 LLM 为每个违规项编写简短的风险解释和验证提示,并附带指向匹配的 Microsoft Learn 文档的链接。
- 确定性修复引擎修补有问题的属性并输出统一的 diff。
- 修补后的文件会被重新扫描,报告显示它现在通过了检查,违规数为 0。这就是证据。
## 为什么它与众不同
现在有很多工具在做“AI 扫描 IaC 并发起 PR”。本工具做出了三个大多数工具都会弄错的有意选择。
### 🔒 本地优先 / 私有 / 零成本
一切都通过本地 LLM 在你的机器上运行。你的 Terraform 通常编码了网络拓扑、资源名称和安全态势,这些都不会被发送到第三方 LLM API。没有按次审查的 token 账单,也没有数据外泄风险。大多数竞争对手会将你的 IaC 发送到云端 API,并告诉你先剥离敏感信息。
### ✅ 可证明的修复
修复不仅是生成的,而且是经过验证的。修补后的 Terraform 会针对相同的策略集重新评估,报告显示 `0 violations`。干净的重新扫描是修复正确的确凿证据,而不是充满希望的“看起来没问题”。
### 🎯 确定性修复,AI 用于理解
LLM 负责解释;它不编写修复方案。修复来自于确定性的规则→属性映射,因此它是可重现的,并且没有幻觉。这涵盖了明确的情况(“将 TLS 设置为 1.2”,“禁用公共访问”)。依赖上下文的情况,比如“允许哪个 CIDR?”,则留给人工批准。
## 架构
```
flowchart LR
TF["terraform/main.tf
(insecure baseline)"] -->|terraform plan -json| PLAN["tfplan.json"] PLAN -->|opa eval| OPA{"OPA / Rego
policies"} OPA -->|violations.json| EXP["explainer.py"] subgraph LOCAL["100% local"] EXP -->|parallel calls| OLLAMA[("local LLM
(on your machine)")] OLLAMA --> EXP end EXP --> REPORT["explanations.md
risk · fix · verify"] EXP -->|deterministic map| FIX["main_fixed.tf
+ unified diff"] FIX -.->|re-scan| OPA OPA -.->|0 violations ✓| PROOF["✅ proof"] DOCS[/"MS Learn
doc refs"/] --> REPORT ``` ## 快速开始 **前置条件:** `terraform`、`opa`、`jq`、`az`(已登录)、本地 LLM runtime(默认为 Ollama)、`python3`。 ``` # 0. 验证你的 toolchain make tools-check # 1. 扫描: terraform plan -> OPA -> 违规 (exit 2 = 发现违规,符合预期) make scan # 2. 解释: 本地 LLM 为每个违规编写风险 + 修复 + 验证 make explain # 3. 修复: 编写修复后的 Terraform 文件 + unified diff make remediate # 4. 验证: 重新扫描修复后的 Terraform 并证明它通过了 gate (0 违规) make verify # 或端到端运行整个 story make demo ``` ## 测试 ``` make test # runs the OPA policy tests + the Python unit tests ``` - **OPA** (`policies/**/*_test.rego`):检查每条规则在违规资源上是否触发, 并在合规资源上保持静默,此外还有全策略检查(完全合规 → 0 拒绝,完全不安全 → 触发所有规则)。 - **pytest** (`tests/test_explainer.py`):针对解析器、prompt 构建器、 确定性修复程序和异步 LLM fan-out 的单元测试。LLM 被 mock,因此该测试套件 速度快、具有确定性,并且 不需要网络或本地模型。 ## LLM 后端(可插拔) 解释器默认本地优先(Ollama, `qwen2.5-coder:3b`),因此没有任何数据会离开 你的机器。要改用托管模型,只需设置一个环境变量。pipeline 的其余部分 (扫描、修复、SARIF、验证)保持不变。 ``` # default — 本地,私有 ollama pull qwen2.5-coder:3b make explain # Azure OpenAI export LLM_BACKEND=azureopenai export AZURE_OPENAI_ENDPOINT="https://.openai.azure.com"
export AZURE_OPENAI_API_KEY="..."
export AZURE_OPENAI_DEPLOYMENT=""
make explain
# Anthropic
export LLM_BACKEND=anthropic
export ANTHROPIC_API_KEY="..."
make explain
```
后端位于 `src/explainer.py` 中一个小型 `LLMBackend` 抽象之后
(`get_backend()` 解析 `--backend`/`$LLM_BACKEND`),因此添加另一个 provider 就是一个
类。单元测试 mock 了该接口,因此测试套件永远不会触及真实模型。
## 目前能检测到的内容
策略集按资源类别组织在 `policies//` 下:
**Storage Account** (`policies/storage/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-STORAGE-001` | high | Nested blobs 必须非公开 |
| `AZ-STORAGE-002` | medium | 禁用 Shared access key 认证 |
| `AZ-STORAGE-003` | high | 禁用公共网络访问 |
| `AZ-STORAGE-004` | medium | 最低 TLS 版本为 `TLS1_2` |
| `AZ-STORAGE-005` | high | 强制仅限 HTTPS 流量 |
**Network Security Group** (`policies/network/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-NSG-001` | high | 没有从公共源(`*`/`0.0.0.0/0`/`Internet`)到敏感/任意端口的入站 `Allow` |
| `AZ-NSG-002` | medium | 没有打开**所有**端口的入站规则(`destination_port_range = "*"`) |
**Key Vault** (`policies/keyvault/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-KV-001` | high | 启用 Purge protection |
| `AZ-KV-002` | high | 禁用公共网络访问 |
**SQL Server** (`policies/sql/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-SQL-001` | high | 禁用公共网络访问 |
| `AZ-SQL-002` | medium | 最低 TLS 版本为 `1.2` |
**App Service** (`policies/appservice/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-APP-001` | high | 强制 `https_only` |
| `AZ-APP-002` | medium | `site_config` 最低 TLS 版本为 `1.2` |
**Managed Disk** (`policies/disk/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-DISK-001` | high | 禁用公共网络访问 |
| `AZ-DISK-002` | medium | 网络访问策略不是 `AllowAll` |
**Cosmos DB** (`policies/cosmos/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-COSMOS-001` | high | 禁用公共网络访问 |
**AKS** (`policies/aks/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-AKS-001` | high | 禁用本地账户 |
| `AZ-AKS-002` | medium | 启用 Azure Policy add-on |
**Container Registry** (`policies/acr/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-ACR-001` | high | 禁用 Admin user |
| `AZ-ACR-002` | medium | 禁用公共网络访问 |
**Log Analytics** (`policies/loganalytics/`)
| 规则 | 严重程度 | 检查内容 |
|------|----------|--------|
| `AZ-LOG-001` | medium | 禁止通过公共互联网进行查询访问 |
## 持续集成
`.github/workflows/policy-scan.yml` 在每次 pull request 和推送到 `main` 时运行:
- **`tests` 作业** 运行 OPA 策略测试和 Python 单元测试。
- **`policy-scan` 作业** 针对提交的 Terraform 计划
fixture(`examples/insecure_plan.json`)评估策略集,然后:
- 将违规项转换为 SARIF(`scripts/opa_to_sarif.py`)并上传它们,以便
发现结果显示在仓库的 **Security ▸ Code scanning** 标签页中,包含文件位置和
严重程度;
- 发布 PR 评论(就地更新,不重复)列出每个违规项及其
确定性修复。
CI 特意设计为无云且无 LLM。它扫描计划 fixture 而不是调用
Azure,并且 AI 解释保留为本地的 `make explain` 步骤,因此即使在 CI 中,也能保证“你的 IaC 永远不会离开你的机器”。
## 项目布局
```
.
├── terraform/main.tf # intentionally-insecure Azure baseline (10 resource types)
├── policies/ # OPA policy set (Rego v1), one folder per category
│ ├── storage/ network/ keyvault/ sql/ appservice/
│ └── disk/ cosmos/ aks/ acr/ loganalytics/ # each: rules + tests
├── scripts/scan_iac.sh # plan -> json -> opa eval pipeline
├── scripts/opa_to_sarif.py # OPA violations -> SARIF (for the Security tab)
├── src/explainer.py # local-LLM explainer + deterministic remediator
├── examples/insecure_plan.json # sanitized plan fixture used by CI
├── Makefile # scan / explain / remediate / verify / demo / test
└── .scan/ # generated reports (sample output kept in repo)
```
## 许可证
[MIT](./LICENSE)
(insecure baseline)"] -->|terraform plan -json| PLAN["tfplan.json"] PLAN -->|opa eval| OPA{"OPA / Rego
policies"} OPA -->|violations.json| EXP["explainer.py"] subgraph LOCAL["100% local"] EXP -->|parallel calls| OLLAMA[("local LLM
(on your machine)")] OLLAMA --> EXP end EXP --> REPORT["explanations.md
risk · fix · verify"] EXP -->|deterministic map| FIX["main_fixed.tf
+ unified diff"] FIX -.->|re-scan| OPA OPA -.->|0 violations ✓| PROOF["✅ proof"] DOCS[/"MS Learn
doc refs"/] --> REPORT ``` ## 快速开始 **前置条件:** `terraform`、`opa`、`jq`、`az`(已登录)、本地 LLM runtime(默认为 Ollama)、`python3`。 ``` # 0. 验证你的 toolchain make tools-check # 1. 扫描: terraform plan -> OPA -> 违规 (exit 2 = 发现违规,符合预期) make scan # 2. 解释: 本地 LLM 为每个违规编写风险 + 修复 + 验证 make explain # 3. 修复: 编写修复后的 Terraform 文件 + unified diff make remediate # 4. 验证: 重新扫描修复后的 Terraform 并证明它通过了 gate (0 违规) make verify # 或端到端运行整个 story make demo ``` ## 测试 ``` make test # runs the OPA policy tests + the Python unit tests ``` - **OPA** (`policies/**/*_test.rego`):检查每条规则在违规资源上是否触发, 并在合规资源上保持静默,此外还有全策略检查(完全合规 → 0 拒绝,完全不安全 → 触发所有规则)。 - **pytest** (`tests/test_explainer.py`):针对解析器、prompt 构建器、 确定性修复程序和异步 LLM fan-out 的单元测试。LLM 被 mock,因此该测试套件 速度快、具有确定性,并且 不需要网络或本地模型。 ## LLM 后端(可插拔) 解释器默认本地优先(Ollama, `qwen2.5-coder:3b`),因此没有任何数据会离开 你的机器。要改用托管模型,只需设置一个环境变量。pipeline 的其余部分 (扫描、修复、SARIF、验证)保持不变。 ``` # default — 本地,私有 ollama pull qwen2.5-coder:3b make explain # Azure OpenAI export LLM_BACKEND=azureopenai export AZURE_OPENAI_ENDPOINT="https://
标签:AI风险缓解, Azure, DevSecOps, ECS, LNA, OPA, Terraform, 上游代理, 关系图谱, 基线检查, 本地大模型, 策略即代码, 聊天机器人安全, 逆向工具, 靶场