# Integrity Guard（完整性守护）V1.0

单节点资产完整性守护服务。零外部依赖、纯 Python 标准库、单文件可审计。

它的能力边界只有一句话：**它能向你证明某块东西没有被改过，证明不了它是否"正确"。**

---

## 一、它做什么

| 能力 | 说明 | 你怎么自己验 |
|---|---|---|
| 四态锁 | 对文件登记熔断位，四种语义：不可变 / 版本可变 / 仅追加 / 根锚 | 改一个字节，`verify` 立刻报 `DRIFT` |
| 链式哈希 | 每个熔断位的 `bit_hash` 绑定上一位，改中间任何一位都会断链 | `record_ok=false` |
| 度量根 | 对一组文件算聚合 SHA256 根，与基线比对 | `measure` 输出 `drift` 列表 |
| Ed25519 签名 | 纯 Python 实现，用 RFC 8032 官方向量自测 | `selftest.py` 跑三个官方向量 |
| 授权与试用 | 30 天试用、许可验签、时钟回拨检测 | 改 `license.json` 任何字段，状态变 `invalid` |
| 签名凭据 | `prove` 端点对度量根 + 随机数签名，可被第三方离线验签 | `verify` 端点或本地验签 |

## 二、它不做什么（必须明确）

- **不声称硬件级不可绕过**。没有 TEE/TPM 的机器上，root 权限者可以改文件、也可以改本服务。它保证的是"改动会被发现"，不是"改不动"。
- 不做自动修复。发现漂移只报告，不写回目标文件。
- 不做多租户、不做 HA。单客户单机。
- 不判断业务规则对不对，只判断资产有没有变。

## 三、30 天试用

- 首次启动自动进入 `trial`，30 天，无需申请。
- 试用期内全部只读端点可用。
- 重装**不会**重置试用：`trial_state.json` 始终保留。
- 时钟回拨会被检出（`clock_rollback_detected`），直接判过期。
- 试用到期后 `measure` / `bits` 返回 403 `license_required`，`health` 仍可用。

## 四、安装

```bash
# 一键安装（先验签，再验包哈希，最后才解包）
curl -fsSL https://<host>/integrity-guard/install.sh | bash

# 只验证包，不安装
bash install.sh --package ./ig-1.0.0.tar.gz --manifest ./manifest.json --sig ./manifest.sig --verify-only

# 回滚到上一版
bash install.sh --rollback
```

安装器行为约定：

1. 用内嵌公钥验 `manifest.json` 的**原始字节**签名；失败即退出。
2. 比对 `package_sha256`；不符即退出，不落盘。
3. 覆盖前整份备份旧目录到 `<prefix>.prev`。
4. `license.json` / `trial_state.json` 不在安装目录内，重装不重置。
5. 端口从 8790 起自动顺延，不写死。
6. 有 systemd 用 systemd，无 systemd 降级后台进程并明确告知"非常驻"。
7. 不以 `systemctl` 返回 0 判定成功，改为轮询 `/api/ig/health`。

## 五、使用

```bash
# 生成密钥与配置
python3 /opt/integrity-guard/ig/ig_cli.py init

# 登记要守护的文件（四种语义任选）
python3 /opt/integrity-guard/ig/ig_cli.py add /etc/nginx/nginx.conf IMMUTABLE
python3 /opt/integrity-guard/ig/ig_cli.py add /var/lib/app/ledger.db APPEND_ONLY
python3 /opt/integrity-guard/ig/ig_cli.py add /etc/app/version.json VERSIONED

# 写度量基线、校验、看漂移
python3 /opt/integrity-guard/ig/ig_cli.py baseline
python3 /opt/integrity-guard/ig/ig_cli.py verify
python3 /opt/integrity-guard/ig/ig_cli.py measure
```

HTTP 端点（只绑 `127.0.0.1`）：

```
GET  /api/ig/health    存活与授权摘要
GET  /api/ig/pubkey    签名公钥 + 指纹
GET  /api/ig/status    授权/试用状态
GET  /api/ig/measure   度量根 + 漂移列表（需有效授权）
GET  /api/ig/bits      熔断位全量校验（需有效授权）
POST /api/ig/prove     {nonce} -> 签名凭据
POST /api/ig/verify    {payload,signature} -> 验签结果
```

## 六、五分钟自测清单

按顺序做，每步都有明确预期结果：

| # | 动作 | 预期 |
|---|---|---|
| 1 | `python3 selftest.py` | `RESULT: ALL PASS`，含 RFC 8032 三个官方向量 |
| 2 | `ig_cli.py add <某文件> IMMUTABLE` | 输出 `efuse_id` 与 `registry_root_hash` |
| 3 | `ig_cli.py verify` | `VERIFY: PASS` |
| 4 | 改动该文件内容，再 `verify` | 该位 `ok=false`，`detail` 含 `DRIFT` |
| 5 | `ig_cli.py add <sqlite库> APPEND_ONLY` 后追加数据再 `verify` | `prefix_ok rows:50->60 (+10)`，判定 PASS |
| 6 | 把该库重建成更少行，再 `verify` | `TRUNCATED(rows 50->20)`，判定 FAIL |
| 7 | 手工改 `license.json` 的 `edition` 字段 | `/api/ig/status` 变 `invalid` / `signature_invalid` |
| 8 | 把 `trial_state.json` 的 `first_run` 改成 40 天前 | 变 `trial_expired` |
| 9 | `bash install.sh --verify-only` | 输出 `SIGNATURE_OK` + 哈希一致 |
| 10 | 篡改包里任意一个字节，再 `--verify-only` | 哈希不符，退出码非 0 |

第 4、6、7、8、10 步是**负向用例**：一个只会报 PASS 的守护器没有价值，能稳定报 FAIL 才有。

## 七、文件

```
ig/ig_core.py     Ed25519 + 四态锁 + 许可/试用 + 度量 + attestation
ig/ig_service.py  HTTP 只读服务
ig/ig_cli.py      命令行
selftest.py       自测（含官方向量）
install.sh        一键安装器
packaging/        打包与签名
```

## 八、已知限制

- 纯 Python Ed25519 每秒约几十次验签，不适合高 QPS 场景；它是"低频高可信"设计。
- APPEND_ONLY 默认取 sqlite 首个表按 rowid 计算前缀哈希；库结构变更需重新登记并 `supersedes`。
- 密钥在本机生成时，本机持有者也可伪造签名。要让"许可对本机也有效"，签发私钥必须离线。
