aws-samples/sample-identity-recertification-vigil
GitHub: aws-samples/sample-identity-recertification-vigil
VIGIL 是一个无服务器的 AWS 访问权限再认证引擎,通过自动发现资源所有者、发起审查请求并执行权限变更,配合哈希链式证据轨迹来实现云资源权限的周期性合规治理。
Stars: 0 | Forks: 1
# VIGIL:访问权限再认证引擎
VIGIL 是一个独立的、生产级的 AWS **访问权限再认证引擎**。它会
通过资源的 `owner` 标签发现资源,向所有者发起审查请求,接收
所有者的决定(**认证 / 修改 / 撤销**),然后在资源上**持久化地执行由此产生的
权限变更**,并为
每一个决定和每一次应用的变更提供不可变的、哈希链式的证据轨迹。
该引擎集成为先:通过文档化的 REST API 驱动所有行为,因此可以
嵌入到你自己的 UI 背后。本仓库还提供了一个极简的、AWS 控制台风格的
React UI,供所有者和管理员使用。
## 功能概述
1. **发现**:枚举带有 `owner=` 标签的资源,解析谁拥有对
各项资源的访问权限(bucket policy / IAM / ACL),并为一个周期创建按所有者划分的审查项。
2. **请求 / 通知**:通过深层链接向每位所有者发送电子邮件,告知其待处理的审查。
3. **决定**:所有者按
资源或按主体进行认证、修改(移除特定权限)或撤销。
4. **执行**:一个持久化且幂等的 worker 通过可插拔的
**资源连接器**应用变更,对回滚前的状态进行快照,并
记录哈希链式证据。
自动执行功能适用于 **Amazon S3 buckets**、**IAM users** 和 **IAM roles**。
任何其他带标签的资源类型都可完全进行再认证;不支持的类型将回退为
IT 管理员工单,而不是进行不安全的自动变更。通过实现
一个连接器即可添加新类型(参见开发者指南)。
## 仓库结构
```
engine/ # The recertification engine (the product)
README.md # Engine overview
DEVELOPER_GUIDE.md # Full developer documentation
template.yaml # Deployable SAM stack (engine only)
openapi.yaml # REST API contract for client UIs
src/
api/ # REST API handler (cycles, reviews, decisions, snapshots, rollback)
discovery/ # Owner-tag discovery + access enumeration
enforcer/ # SQS consumer -> connectors (durable enforcement)
notifier/ # SES owner notifications
connectors/ # Pluggable resource connectors (S3, IAM user, IAM role) + registry
core/ # Models, decision intake, enforcement orchestration, evidence, rollback
lib/ # config, ddb, hash chain, time, http helpers
tests/ # node:test unit tests
ui/ # React 18 + Vite SPA (Login + Recertification + Discovery admin)
docs/ # Documentation hub + architecture diagram
```
## 架构

该引擎是完全无服务器的。上图所示的流程如下:
1. **请求**:客户端(你的或我们的 UI)使用 Cognito ID
token 调用 **API Gateway** REST API;**Amazon Cognito** 用户池授权方 (`COGNITO_USER_POOLS`)
验证该 token,然后由 `recert-api` 处理请求。
2. **发现与通知**:启动一个周期会调用 `recert-discovery`,它通过
**Resource Groups Tagging API** 根据资源的 `owner` 标签查找资源,并构建按所有者划分的审查项;`recert-notifier` 通过 **Amazon SES** 向每位所有者发送电子邮件。
3. **持久化执行**:当所有者做出决定时,`recert-api` 会写入该决定并将其
排队(幂等)到 **SQS** 队列中。`recert-enforcer` 消费该队列并执行
`snapshot → apply → verify`。失败时会进行重试,并通过 **CloudWatch**
警报将消息转入 **DLQ** (死信队列)。
4. **作用域连接器**:执行器从不直接调用 AWS API;它将应用到目标资源(**S3 bucket**、**IAM user/role**、
**EC2 instance**)的*作用域内*变更委托给可插拔的连接器。任何不支持的类型都会被路由到工单,而不是进行猜测。
5. **状态与证据**:周期、审查、决定和快照存在于单个 **DynamoDB**
表中;每个操作都会追加到哈希链式的证据轨迹中,可选择性地镜像到
**S3 Object Lock (WORM)** bucket 中,以实现不可变的、可防御的记录。
发现和通知作为独立的 Lambda 函数运行,在创建周期时和由 EventBridge 计划触发。
## 前置条件
- AWS CLI v2
- AWS SAM CLI v1.100+
- Node.js 20+(引擎运行在 `nodejs24.x` Lambda 运行时上,该运行时提供 AWS SDK v3)
## 快速开始
```
cd engine
# 构建和部署(如果你不提供,会创建自己的 Cognito pool)
sam build
sam deploy --guided \
--stack-name recert-engine-dev \
--parameter-overrides Stage=dev SesSenderEmail=you@example.com \
UiBaseUrl=https://your-ui.example.com
```
部署会输出 API endpoint、DynamoDB 表名、SQS 队列 URL,以及(如果已创建)
Cognito 用户池和客户端 ID。
在用户池中创建一个管理员/所有者用户:
```
aws cognito-idp admin-create-user --user-pool-id \
--username owner@example.com --user-attributes Name=email,Value=owner@example.com \
--message-action SUPPRESS
aws cognito-idp admin-set-user-password --user-pool-id \
--username owner@example.com --password '' --permanent
aws cognito-idp admin-add-user-to-group --user-pool-id \
--username owner@example.com --group-name owner
```
为资源打上标签以便其被发现,然后从 UI 的 **Discovery** 页面启动一个周期,或者:
```
curl -X POST "$API/cycles" -H "Authorization: " \
-H 'Content-Type: application/json' -d '{"cycleType":"AD_HOC"}'
```
完整的部署、API 和扩展说明请参见
**[开发者指南](engine/DEVELOPER_GUIDE.md)**。
## UI
`ui/` 是一个 React 18 + Vite 单页应用,其样式设计旨在匹配 AWS 管理控制台
(Cloudscape 外观,Amazon Ember 字体)。它仅包含两个区域:
- **再认证**:所有者审查并对他们的资源做出决定(按资源和
按主体)。
- **发现**(仅限管理员):启动一个新的周期并查看运行历史记录及结果计数
(已认证 / 已撤销 / 已修改 / 待处理,完成度 %)。
在 `ui/.env` 中配置部署后的 `VITE_API_URL`、`VITE_COGNITO_USER_POOL_ID` 和
`VITE_COGNITO_CLIENT_ID`,然后执行 `npm run build` 并托管 `dist/`(例如在 S3 +
CloudFront 上)。
## 配置说明
| 变量 | 必填 | 用途 |
|---|---|---|
| `TABLE_NAME` | 是 | DynamoDB 单表存储 |
| `ENFORCEMENT_QUEUE_URL` | 是 | API 将决定排入的 SQS 队列 |
| `EVIDENCE_BUCKET` | 否 | 用于证据镜像的 S3 Object Lock (WORM) bucket |
| `SES_SENDER_EMAIL` | 是 | 用于发送所有者邮件的已验证 SES 发件人 |
| `UI_BASE_URL` | 是 | 邮件深层链接中使用的 Base URL |
| `RECERT_DEADLINE_DAYS` | 否 (14) | 审查窗口期 |
| `MANAGEMENT_ACCOUNT_ID` | 否 | 如果未设置,则在运行时从 STS 解析 |
| `CROSS_ACCOUNT_ROLE_NAME` | 否 (`VIGILCrossAccountRole`) | 在成员账号中扮演的 Role |
## 测试说明
```
cd engine
node --test tests/connectors.test.mjs
```
连接器测试断言了生产环境的正确性不变量:作用域撤销(无过度宽泛的
分离)、作用域修改、完全撤销、IAM role/user 部分操作以及幂等执行。
## 安全性
- REST API 的每次请求都需要有效的 Cognito token (`COGNITO_USER_POOLS`
授权方)。所有者身份派生自 token,而不是请求体。
- 每个 Lambda 都使用限定于其执行操作的最小权限 role。
- 执行是**作用域受限的**:撤销/修改仅影响目标资源。当
访问权限是通过 IAM 授予且无法在原处安全缩小时,引擎会在
资源上添加作用域内的显式 `Deny`,而不是直接修改主体的 IAM policies。
- 每一个决定和变更都会记录在一个仅可追加的、哈希链式的证据轨迹中;
启用 `EVIDENCE_BUCKET` 以实现 WORM (Object Lock) 保留。
## 清理说明
```
cd engine
sam delete --stack-name recert-engine-dev
```
DynamoDB 表和(如果已启用的)证据 bucket 使用 `DeletionPolicy: Retain`。如果你
启用了 WORM 证据 bucket,在它的 Object Lock
保留期到期之前,其中的对象无法被删除。
## 许可证
MIT-0。本项目作为教育和演示目的的示例提供;
在没有进行额外安全审查和强化的情况下,不适用于生产环境。
标签:AWS, DPI, Serverless, Streamlit, 云安全治理, 权限管理, 模型越狱, 自定义脚本, 访问控制