Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
405 changes: 401 additions & 4 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions rvds/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,13 @@
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
url = "2"
sha2 = { workspace = true }
async-trait = { workspace = true }
hex = { workspace = true }
rand = "0.8"
web3 = { version = "0.19", default-features = false, features = ["http", "signing"] }
ethabi = "18"
secp256k1 = { version = "0.27", features = ["rand"] }
base64 = { workspace = true }


12 changes: 10 additions & 2 deletions rvds/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- **HTTP API(Actix-web)**:暴露 `/rvds/*` 接口,负责参数校验与响应封装。
- **订阅注册表(Subscriber Registry)**:用 `HashSet` 存储已注册的 Trustee 基址,持久化于 `data/rvds/subscribers.json`。
- **事件转发器(Forwarder)**:接收发布事件后,构造 RVPS 期望的 `message` 包裹并并发调用各 Trustee 的 `/api/rvps/register`。
- **账本记录器(Ledger Recorder)**:对 `PublishEventRequest` 做规范化哈希,写入外部不可篡改账本(默认 noop,可配置 HTTP / 以太坊网关),返回记录凭据,并将审计凭据随 payload 一并下发。
- **配置与启动器(Config / Bootstrap)**:从环境变量加载监听地址、数据目录、下游调用超时等参数。

## 数据模型
Expand All @@ -27,7 +28,14 @@
{
"artifact_type": "rpm",
"slsa_provenance": ["..."], // 多个 provenance(原文或 base64),数组形式
"artifacts_download_url": ["https://...rpm"]
"artifacts_download_url": ["https://...rpm"],
"audit_proof": { // 可选,账本回执
"backend": "ethereum-gateway",
"handle": "0x<tx_hash>",
"event_hash": "<sha256(canonical payload)>",
"payload_hash": "<sha256(payload)>",
"payload_b64": "<base64 of payload>"
}
}
```
- **转发给 RVPS 的请求**
Expand All @@ -45,7 +53,7 @@
- 返回:已新增的地址列表。
- `POST /rvds/rv-publish-event`
- 功能:校验事件并转发到全部 Trustee。
- 返回:每个 Trustee 的投递结果(成功/失败与错误信息)。
- 返回:每个 Trustee 的投递结果(成功/失败与错误信息),以及可选的 ledger 记录凭据

## 工作流程

Expand Down
77 changes: 77 additions & 0 deletions rvds/docs/audit-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# 第三方审计操作手册(RVDS + RVPS + 以太坊账本)

本手册指导审计者仅凭 RVPS 返回的参考值(含审计字段)完成端到端验证,确认 RVDS 发布事件已被写入不可篡改账本(以太坊为例),并与 RVPS 内的参考值一致。账本侧仅写入摘要(hash),原文由 RVPS 的 `audit_proof.payload_b64` 提供。

## 前提信息
- RVPS 查询到的 `ReferenceValue`,其中可选字段 `audit_proof`:
```json
{
"name": "...",
"hash-value": [...],
"audit_proof": {
"backend": "ethereum-gateway",
"handle": "0x<tx_hash>",
"event_hash": "<sha256 of canonical PublishEventRequest>",
"payload_hash": "<sha256 of payload>",
"payload_b64": "<base64 of canonical payload>"
}
}
```
- RVDS 账本记录:在 ledger_receipt 中会返回与 `audit_proof` 对应的字段。
- 合约地址与链信息:`ETH_CONTRACT_ADDRESS`,链 ID,RPC/浏览器入口。

## 步骤 1:本地重算并校验摘要
1. 从 RVPS 返回的 `audit_proof.payload_b64` 解码得到 canonical `PublishEventRequest` JSON。
2. 本地计算:
- `sha256(payload)` → 对比 `payload_hash`。
- `sha256(canonical payload)` → 对比 `event_hash`。
若不一致,审计失败。

## 步骤 2:链上验证交易与事件
1. 取 `handle`(`tx_hash`),在浏览器或本地节点查询:
- 浏览器:输入 tx_hash。
- 节点:`eth_getTransactionReceipt <tx_hash>`.
2. 确认交易成功,找到来自合约 `RvdsEventLog` 的 `EventRecorded` 事件。
3. 解码事件参数(浏览器通常自动解码):
- `eventHash` (bytes32) 应等于 `audit_proof.event_hash`。
- 第二个参数存储的是 `payloadHash`(摘要上链),应等于 `audit_proof.payload_hash`。

## 步骤 3:对照 RVPS 参考值
1. 从 `payload` 中的 `slsa_provenance` 解析 `subject[].digest`(和 RVPS 逻辑一致)。
2. 确认解析出的制品哈希与 RVPS 返回的 `hash-value` 完全匹配。
3. 如有多份参考值(多个 subject),逐一对应。

## 命令行示例
假设已拿到 `tx_hash`、`event_hash`、`payload_hash`、`payload_b64`:

```bash
# 1) 查询交易(需已配置 ETH_RPC_URL)
curl -s -X POST "$ETH_RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_getTransactionReceipt",
"params":["<tx_hash>"],
"id":1
}' | jq .

# 2) 解析 logs,确认事件里 eventHash == audit_proof.event_hash,payloadHash == audit_proof.payload_hash
# 3) 解码 RVPS 提供的 payload_b64 并重算 hash
echo "<payload_b64_from_rvps>" | base64 -d > payload.json
PAYLOAD_HASH_LOCAL=$(sha256sum payload.json | awk '{print $1}')
echo "local payload hash: $PAYLOAD_HASH_LOCAL"
# 对比 audit_proof.payload_hash / event_hash
```

## 浏览器快速校验
1. 打开区块浏览器,输入 `tx_hash`。
2. 在 Logs/Events 中找到 `EventRecorded`:
- `eventHash` 对比 `audit_proof.event_hash`。
- data/decoded payloadHash 对比 `audit_proof.payload_hash`。
- 原文由 RVPS 的 `payload_b64` 提供,在本地解码后重算哈希比对。

## 注意事项与影响
- 账本只写 hash,原文不上链;RVPS 存储 payload_b64 供审计端重算哈希。
- `audit_proof` 可选,未开启账本时保持兼容(字段缺失不影响现有接口)。
- 若使用其它账本(如 Rekor),在 `audit_proof.backend/handle` 写入对应证明,验证时使用相应工具;结构不变。

4 changes: 4 additions & 0 deletions rvds/docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
- `RVDS_LISTEN_ADDR`:监听地址,默认 `0.0.0.0:8090`
- `RVDS_DATA_DIR`:订阅持久化目录,默认 `data/rvds`
- `RVDS_FORWARD_TIMEOUT_SECS`:转发超时秒数,默认 `10`
- `RVDS_LEDGER_BACKEND`:`none`(默认)、`http`、`eth`
- `RVDS_LEDGER_HTTP_ENDPOINT` / `RVDS_LEDGER_HTTP_API_KEY`:账本网关(http)配置
- `RVDS_LEDGER_ETH_GATEWAY` / `RVDS_LEDGER_ETH_GATEWAY_API_KEY`:以太坊网关配置
- `RUST_LOG`:日志等级,如 `info,rvds=debug`

## 源码构建运行
Expand Down Expand Up @@ -73,5 +76,6 @@ curl -k -X POST http://localhost:8090/rvds/rv-publish-event \

- 在 release workflow 中生成 `PublishEventRequest`,通过 `curl`/`gh api` 等 POST 到 RVDS。
- RVDS 会自动并发转发到已注册的 Trustee;失败结果会返回在响应中,供重试或告警。
- 若配置了 ledger,RVDS 会在响应和下游 payload 中附带 `audit_proof`(含 event_hash/payload_hash/payload_b64、tx 句柄等),便于 RVPS/审计使用。


72 changes: 72 additions & 0 deletions rvds/docs/eth-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# RVDS 以太坊网关使用指南

> 作用:提供一个具备签名与上链能力的 HTTP 网关,接受 RVDS 的事件摘要请求,调用链上合约 `record(bytes32 eventHash, string payloadHash)`,并返回真实交易哈希。

## 功能

- 端点:`POST /record`
- 请求:
```json
{
"event_hash": "0x<sha256 hex>", // 32字节
"payload": "canonical PublishEventRequest JSON"
}
```
- 响应:
```json
{ "tx_hash": "0x<real-ethereum-tx-hash>" }
```
- 内部逻辑:
- 对 payload 做 sha256,作为 `payloadHash`。
- ABI 编码调用合约 `record(eventHash, payloadHash)`。
- 使用私钥签名交易并通过 RPC 发送,返回 tx_hash。
- 默认 gas 200000,gas_price 来自链上 `eth_gasPrice`。

## 启动

```bash
cd /root/design/trustee/rvds
cargo run --bin eth_gateway
```

必需环境变量:
- `ETH_RPC_URL`:以太坊 RPC 地址(可用公用节点或自建节点)
- `ETH_PRIVATE_KEY`:0x 前缀的私钥(用于签名)
- `ETH_CONTRACT_ADDRESS`:已部署的合约地址(示例见下)

可选环境变量:
- `ETH_GATEWAY_LISTEN`:监听地址,默认 `0.0.0.0:8095`
- `ETH_CHAIN_ID`:链 ID,默认 `1`

## 合约示例(Solidity 0.8.x)

```solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

contract RvdsEventLog {
event EventRecorded(bytes32 indexed eventHash, string payloadHash, address indexed sender, uint256 blockNumber);

function record(bytes32 eventHash, string calldata payloadHash) external {
emit EventRecorded(eventHash, payloadHash, msg.sender, block.number);
}
}
```

部署后将合约地址写入 `ETH_CONTRACT_ADDRESS`。

## 与 RVDS 对接

在 RVDS 配置:
- `RVDS_LEDGER_BACKEND=eth`
- `RVDS_LEDGER_ETH_GATEWAY=http://<gateway-host>:8095/record`
- `RVDS_LEDGER_ETH_GATEWAY_API_KEY`(当前未校验,可留空)

RVDS 在 `/rvds/rv-publish-event` 时调用网关,`ledger_receipt.handle` 将包含真实链上 `tx_hash`。

## 生产注意

- 私钥务必放在可信环境,可优先使用 KMS/HSM 管理;当前示例从环境变量读取,仅适用于 PoC。
- 请确认 gas 费、nonce 管理符合预期;当前实现使用链上 `gasPrice`,固定 gas=200000,可按需调整或改为 `eth_estimateGas`。
- 如需鉴权,可在网关增加 API Key/Token 校验,并在 RVDS 设置 `RVDS_LEDGER_ETH_GATEWAY_API_KEY`。

2 changes: 2 additions & 0 deletions rvds/docs/flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
}
```
- 并发调用每个 Trustee 的 `https://<trustee>/api/rvps/register`。
- 同步将事件摘要(canonical + sha256)写入外部账本(若启用),返回 ledger 凭据,并把审计字段(`audit_proof`,含 event_hash/payload_hash/payload_b64)附在 payload 中下发。
4. **校验与入库**
- Trustee Gateway 将请求转给 RVPS gRPC `RegisterReferenceValue`。
- RVPS 通过 `slsa` extractor:
- 解析 `payload` 得到 `artifact_type/slsa_provenance[]/artifacts_download_url`。
- 针对每个 provenance(raw JSON 或 base64 JSON)解析 subject,支持多份 provenance。
- 抽取 `subject[].digest`(优先 `sha256`),生成 `ReferenceValue`(默认 12 个月有效)。
- 将 `audit_proof` 落在 ReferenceValue(便于后续第三方审计)。
- 调用存储接口写入参考值。
5. **消费**
- 上游(如 AS)调用 RVPS `query_reference_value` 获取可信哈希用于度量验证。
Expand Down
107 changes: 107 additions & 0 deletions rvds/docs/ledger-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# RVDS 发布事件不可篡改账本记录设计

## 背景与目标

- 发布事件需要“公开可审计、不可篡改”地留痕(典型载体:区块链 / 透明日志)。
- RVDS 在收到 `PublishEventRequest` 时,除转发给 Trustee 外,还需将事件摘要写入外部账本,并返回记录凭据。
- 设计需可扩展:不同场景可接入不同账本(链、透明日志、第三方网关)。

## 设计概览

- 新增 **Ledger Recorder** 组件,核心是 `LedgerAdapter` 抽象:
- `record_event(event, canonical_payload) -> LedgerReceipt`
- 内置实现:`NoopLedger`(默认)、`HttpLedger`(对接外部账本网关)、`EthGatewayLedger`(通过以太坊网关写入链上日志)。
- 事件哈希:
- 使用 canonical JSON(对 `PublishEventRequest` 进行稳定序列化)后计算 `SHA256`,得到 `event_hash` 与 `payload_hash`。
- 账本端仅写入摘要(hash),不携带原文;原始 payload 以 base64 形式保存在 RVPS 的 `audit_proof` 中,供审计者校验。
- RVDS API 回包增强:
- `PublishResponse` 增加 `ledger_receipt`,便于 CI 在发布日志中附带证明。

## 账本适配层

### 接口
```rust
pub trait LedgerAdapter {
async fn record_event(&self, event: &PublishEventRequest, canonical_payload: &str) -> Result<LedgerReceipt>;
}
```

### 内置实现
- `NoopLedger`:不写外部账本,返回合成的 `event_hash`。
- `HttpLedger`:POST `{event_hash, payload}` 到外部网关;网关可自行决定只上链 hash 或其它策略;`ledger_receipt` 会携带本地的 `payload_b64` 供审计者使用。
- `EthGatewayLedger`:面向以太坊链,通过网关 POST `{event_hash, payload}`,网关签名调用合约时仅写入摘要(hash),返回 `tx_hash`;`ledger_receipt` 同样附带 `payload_b64`。

### 选择与配置
- 环境变量:
- `RVDS_LEDGER_BACKEND`:`none`(默认)、`http` 或 `eth`
- `RVDS_LEDGER_HTTP_ENDPOINT`:后端网关地址(`http` 模式必填)
- `RVDS_LEDGER_HTTP_API_KEY`:可选鉴权
- `RVDS_LEDGER_ETH_GATEWAY`:以太坊网关地址(`eth` 模式必填)
- `RVDS_LEDGER_ETH_GATEWAY_API_KEY`:以太坊网关鉴权(可选)
- 未来扩展:
- 可增加 `RekorAdapter`(Sigstore 透明日志)、`EthereumAdapter`(合约记录 `event_hash`),只需实现 `LedgerAdapter` 并在工厂中注册。

## 时序(含账本)

1. CI 调用 `POST /rvds/rv-publish-event`。
2. RVDS 规范化序列化 payload,计算 `event_hash`。
3. Ledger Recorder 通过适配器写入外部账本,获得 `ledger_receipt`(可能为空)。
4. RVDS 按原逻辑并发转发给各 Trustee 的 `/api/rvps/register`。
5. RVDS 返回(示例):
```json
{
"forwarded": [...],
"ledger_receipt": {
"backend": "http",
"handle": "<opaque-proof>",
"event_hash": "<sha256>",
"payload_hash": "<sha256>",
"payload_b64": "<base64 of canonical payload>"
}
}
```
6. 可选:Trustee/RVPS 存储或透传 `ledger_receipt`,便于后续审计。

- ## 容错与安全
-
- Ledger 失败策略:记录 warning 并继续转发(可根据需求改成强制失败)。
- 哈希基于 canonical payload,避免字段顺序影响;业务如需更强规范,可固定字段排序/移除冗余。
- 如需强制验证 ledger 成功,可在生产环境加开关:失败则拒绝发布。
-
- ## 实现范围(本次)
-
- 新增适配层与配置,默认 `none`,支持 `http` 网关写入,以及 `eth`(以太坊网关)模式。
- 在 `PublishResponse` 返回 `ledger_receipt`。
- 文档同步:architecture、flow 以及本设计说明。

## 以太坊链设计(网关模式)与合约示例

- 模式:RVDS 通过 `EthGatewayLedger` 把 `{event_hash, payload}` POST 到以太坊网关;网关负责签名并调用链上合约时仅写入摘要(hash),返回 `tx_hash`。原文不链上存储,`payload_b64` 仅在 RVPS 中保存。
- 网关接口建议:
- `POST /record` `{ "event_hash": "<hex>", "payload": "<canonical json>" }`
- 返回 `{ "tx_hash": "0x..." }`
- 合约示例(Solidity 0.8.x):
```solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

contract RvdsEventLog {
event EventRecorded(bytes32 indexed eventHash, string payloadHash, address indexed sender, uint256 blockNumber);

function record(bytes32 eventHash, string calldata payloadHash) external {
emit EventRecorded(eventHash, payloadHash, msg.sender, block.number);
}
}
```
- 部署与网关步骤(概要):
1. 选择链(主网/测试网)并配置 RPC。
2. 部署合约 `RvdsEventLog`,记录下合约地址。
3. 网关持有链上账户私钥,暴露 REST 接口 `/record`:
- 将 `event_hash`、`payloadHash`(可使用同样的 sha256/canonical)调用合约 `record`。
- 返回 `tx_hash` 供 RVDS 作为 `handle`。
4. 在 RVDS 配置:
- `RVDS_LEDGER_BACKEND=eth`
- `RVDS_LEDGER_ETH_GATEWAY=https://<your-eth-gateway>/record`
- `RVDS_LEDGER_ETH_GATEWAY_API_KEY=<token>`(若需要)
5. 审计时:根据 `event_hash` 计算后,在链上事件日志中查找 `EventRecorded`,确认对应 `tx_hash` 与区块高度。

Loading
Loading