ChrisInvictus/paved-org
GitHub: ChrisInvictus/paved-org
以 Terraform 实现的 GCP 组织安全基线,通过组织策略、项目工厂和无密钥 GitOps 流水线让不安全状态在平台中无法表示。
Stars: 0 | Forks: 0
# paved-org 🛣️
  
*一个基于代码的 GCP 组织基线:组织级防护栏,一个分发默认安全项目的 project factory,以及行驶在铺设好的道路上的零信任工作负载 —— 受 IAP 保护,通过无密钥的 WIF pipeline 进行部署。
CloudCanary 的防御部分。*
**概览:** 使不安全状态无法表示的组织策略 · 分发默认安全项目的 project factory · 全程无任何导出密钥(端到端的无密钥 WIF/OIDC)· 作为活生生的证明的零信任工作负载(IAP)· 扩展到 AI 智能体:一个 ai-guardrails 模块,在其姐妹项目中的 AI 工作负载检测,以及一份已发布的 MCP 信任边界威胁模型(v1.1 —— STRIDE × OWASP LLM Top 10 2025,多智能体扩展)和分为两部分的实用安全手册。检测部分:[CloudCanary](https://github.com/ChrisInvictus/CloudCanary)。
## 核心理念
大多数组织是在项目存在之后才将安全性附加到项目上 —— 这里一个扫描器,那里一个审查清单,一份没人读的策略文档。paved-org 使**组织本身**成为安全边界。组织策略约束在根层级强制执行并被下面的所有内容继承;project factory 分发的项目在首次 API 调用之前就已经过强化。不安全状态不是被策略文档所禁止的 —— 它们在**平台中根本无法表示**。
这里的所有内容都是 Terraform,通过一个 GitOps pipeline(在 PR 时 plan,在合并时 apply)部署,该 pipeline 使用**零导出的服务账号密钥**向 GCP 进行身份验证。
## 三个阶段
```
Act 1: THE PAVEMENT (org layer)
GCP Organization
├── Org policies (Terraform): the secure-by-default constraint set
├── Folder hierarchy: /workloads, /sandbox
└── Project factory module: vends pre-hardened projects
(baseline APIs, logging sink, no default network,
no default-SA editor grant, labels, budget guard)
Act 2: THE KEYLESS ROAD (deployment identity)
GitHub Actions ──OIDC──> Workload Identity Federation pool
└── deploys everything with ZERO exported service-account keys
plan-on-PR · apply-on-merge · state in a versioned GCS bucket
Act 3: THE WORKLOAD (zero trust in action)
A vended project runs a tiny demo app (Cloud Run)
└── fronted by Identity-Aware Proxy (IAP — Google's ZTNA,
BeyondCorp lineage): no VPN, no public ingress,
every request identity-checked
```
这条铺设好的道路 —— 以及在上面行驶的工作负载。
## 防护栏(阶段 1)
七个组织策略约束,每个都关闭了一类配置错误([`org/policies.tf`](org/policies.tf),每个都有一行威胁模型):
| 约束 | 它消灭了什么 |
|---|---|
| `iam.disableServiceAccountKeyCreation` | 排名第一的 GCP 凭据盗窃载体:永不过期的导出密钥 |
| `iam.automaticIamGrantsForDefaultServiceAccounts` | 诞生时便拥有项目 Editor 权限的默认服务账号 |
| `iam.allowedPolicyMemberDomains` | 对组织目录之外的身份授予 IAM 权限 |
| `compute.skipDefaultNetworkCreation` | 每个新项目中宽松的默认 VPC |
| `compute.vmExternalIpAccess` | 可在互联网上扫描的 VM |
| `storage.uniformBucketLevelAccess` | 每对象 ACL 蔓延 —— 导致公共存储桶事件的根本原因 |
| `sql.restrictPublicIp` | 位于公共互联网上的数据库 |
关于身份治理的说明:现代 GCP 组织在诞生时就有其中几个由 Google 预先强制执行。paved-org **导入**这些默认值到 Terraform state 中,而不是让它们处于无人管理状态 —— 无人管理的默认值就是等待发生的 drift,并且其中一个约束被收紧到了超越 Google 的默认值。完整的故事在 [`docs/bootstrap.md`](docs/bootstrap.md) 中。
## 没有密钥受到伤害(阶段 2)
强制执行 `iam.disableServiceAccountKeyCreation` 的 pipeline 本身在身份验证时**没有任何密钥**:GitHub 的 OIDC 发行者为每个 workflow 运行提供担保,而 Workload Identity Federation 将该短期 token 交换为联合凭据。信任通过属性条件精确固定到一个 repository;部署者服务账号携带最小权限的组织角色(组织策略 + 文件夹管理 —— 刻意不设为 `organizationAdmin`)。
一个违反自身策略的治理层只是做戏。
## 姐妹仓库
**paved-org 预防了 [CloudCanary](https://github.com/ChrisInvictus/CloudCanary) 检测到的内容。** 同时运行两者:预防已知问题,检测 drift。上面的密钥创建约束预防了 CloudCanary 的身份漂移 canary 发出警报的确切事件。
## AI 工作负载安全
将预防/检测的理念扩展到 AI 工作负载:
- [**MCP 信任边界威胁模型**](docs/threat-models/mcp-trust-boundaries.md) —— 五个边界(B1–B5),STRIDE × OWASP LLM Top 10 (2025),带有 IAM 视角和多智能体(agent ↔ agent)扩展(v1.1)。
- [**MCP 安全手册**](docs/runbooks/securing-mcp-setup.md) —— 分为两部分的实用审计:一个托管连接器主机和一个自托管 agent 网关,包含主机强化、一个 fail-closed 的执行批准门,以及一个在 staging 环境验证过的 container。
- [**`modules/ai-guardrails`**](modules/ai-guardrails/) —— 针对 AI 工作负载的组织策略防护栏(经验证的预设约束),这是 [CloudCanary](https://github.com/ChrisInvictus/CloudCanary) 检测内容的预防部分。
## 成本与可重复性
完全基于 GCP 免费试用额度构建。组织层(策略、文件夹、WIF、state)是控制面配置,保持运行的成本为 $0。工作负载层(阶段 3)承载着唯一的实际成本 —— 用于 IAP 的全局外部 HTTPS 负载均衡器,约为 $18/月 —— 因此它大约只存活 48 小时:构建、取证,然后 `terraform destroy`。
销毁/apply 的往返过程已记录在案且可重复。**可重复性才是关键** —— 该 repo 的价值在于代码和证据,而不是一个正在运行的演示。要从裸域名重建,请遵循 [`docs/bootstrap.md`](docs/bootstrap.md)。
## 证据
在 [`docs/evidence/`](docs/evidence/README.md) 中跟踪了状态:
- ✅ 收敛的 plan:`No changes. Your infrastructure matches the configuration.`
- ✅ 在 PR 时 plan,在合并时 apply:提议被渲染出来,合并变为基础设施 —— 全程无密钥
- ✅ 平台拒绝违规行为:组织策略拒绝了 SA 密钥请求;默认的 compute SA 诞生时零权限
- ✅ 自动售货机:由 pull request 创建的强化项目
- ✅ 经双向验证的零信任:IAP 身份挑战和允许路径上断言的身份;对于已认证但未授权的账号返回 403
- ✅ 可重复性:付费层通过构建它的同一个 pipeline 被销毁
## 诚实的局限性
这是一个演示规模的组织,并且也如实说明了这一点:
- **没有多环境提升(promotion)。** 一个组织,一个 state,一个 pipeline 通道。生产环境会添加 dev/nonprod/prod 文件夹,并带有每个环境的 state 和提升门。
- **没有 Security Command Center 集成。** 生产环境会在此类预防性控制之上接入 SCC Premium 以进行态势管理和威胁发现。
- **没有 VPC Service Controls。** 数据渗透防线是真实部署的下一层;此处的任何内容都不与添加它们产生冲突。
- **单人目录。** 基于群组的 IAM(管理员群组、破窗程序)在设计上是存根(stub)状态的;文件夹布局为其留出了空间。
完整的威胁模型(包括已接受的风险)在 [SECURITY.md](SECURITY.md) 中。
## Repo 结构
```
org/ Act 1 + 2: policies, folders, WIF, org logging — live
modules/project-factory/ Act 1: the vending machine — landing in Act 3
workloads/demo/ Act 3: vended project + Cloud Run + IAP — landing in Act 3
docs/ architecture, bootstrap guide, evidence
.github/workflows/ plan-on-PR, apply-on-merge, lint
```
## 路线图
多环境提升 · SCC 集成 · VPC-SC 防线 · 基于群组的 IAM 和破窗 · 作为 factory 默认值的预算防护 · 针对 factory 模块的 Terraform 测试(`terraform test`)。
## License
MIT
标签:ECS, GCP, GitOps, JSONLines, Terraform, 组织基线, 零信任