Monorepo 架构与防越权规范
SayClaw 采用强隔离的 Monorepo 架构(单仓多入口),在保证跨端开发效率的同时,通过 代码级、编译级、运行时、网络层 四层防护彻底杜绝权限越权与代码污染。
1. 代码隔离:Go internal 包机制
为了防止 portal-api (C端) 错误地引用 admin-api (管理端) 的代码导致权限泄露,所有核心业务逻辑必须放置在 internal 目录下。Go 编译器会在编译期直接阻断跨 internal 目录的导入。
标准目录结构:
sayclaw/
├── packages/
│ └── shared/ # 公共依赖(见下文)
├── apps/
│ ├── admin-api/
│ │ ├── cmd/ # 仅做初始化
│ │ └── internal/ # 管理后台核心逻辑(物理上 portal-api 无法 import)
│ └── portal-api/
│ ├── cmd/ # 仅做初始化
│ └── internal/ # C端核心逻辑(物理上 admin-api 无法 import)
2. 依赖隔离:shared 极简原则
packages/shared 层必须极其克制,防止它演变成耦合严重的“垃圾场”。
允许放入 shared 的内容:
- DB Models (GORM Structs, Migration Scripts)
- 无状态纯工具函数 (Utils:如 AES 加密、时间格式化、UUID 生成)
严格禁止放入 shared 的内容:
- 任何具体业务逻辑(如发邮件、计费逻辑、用户注册流程)
- 第三方重度依赖的 SDK Client 初始化逻辑
3. 运行隔离:Deny by Default 鉴权
在路由设计上,抛弃“开发者需记得挂载鉴权中间件”的脆弱依赖。
admin-api的全局 Router Group 必须默认挂载RequireAdmin中间件。- 若需开放特定接口(如登录、Webhook),必须显式标记为
AllowPublic或将其移出默认 Group。 - 安全兜底:即使开发疏忽忘了配置,接口也处于“拒绝访问”的默认安全状态。
4. 物理隔离:双镜像 + 网络 VPC
- 双 Docker 镜像:虽然在同一个代码仓,但在 CI/CD 阶段,
admin-api和portal-api被打包为两个完全独立的基础镜像,彼此不包含对方的二进制文件。 - 网络层隔离:
admin-api容器不分配公网 IP,部署于内网 VPC 中,并附加 IP 白名单与 VPN/证书校验(配合 Cloudflare WAF)。外网攻击者在网络拓扑上无法触达 Admin 服务。