背景
PR #54 のディープレビュー指摘(blocker 2)。
問題
authorize_read(state_node_service.rs)は access policy のロード エラー には fail-closed で拒否する一方、正常に None を得た場合は Ok(()) を返して認証済みの任意の caller に read を許可する。
// No policy exists yet — allow, matching the HTTP read path.
Ok(())
これは理論上の状態ではない:
prepare_create_operations(crdt_repository.rs)が作る Create payload は access_policy: None で、owner policy は別の Update operationとして後から適用される
- 受信側の
apply_operations は個々の operation の失敗をログして処理を継続し、部分適用でも成功を返し得る
→ 「genesis はあるが policy update が無い」レプリカが成立し、そのノードは誰にでも read を許してしまう。
暗号文の機密性は CEK が守るが、これは認可契約の代替にならない。暗号文・履歴・サイズ・更新頻度といったメタデータが漏れ、将来の暗号/鍵管理のバグを即座に平文漏洩へ拡大する。
あるべき修正
- owner policy を genesis payload に原子的に含める(create の時点で policy が存在することを不変条件にする)
- それが入るまでは、policy 欠落は read 拒否とする。明示的な bootstrap 状態が必要なら別の型で表現する
- create / policy update の部分適用を成功として扱わない
テスト観点
- genesis のみを持つレプリカに対する非 owner の read が拒否されること
- policy update が落ちた部分同期状態を再現し、fail-closed になること
関連
背景
PR #54 のディープレビュー指摘(blocker 2)。
問題
authorize_read(state_node_service.rs)は access policy のロード エラー には fail-closed で拒否する一方、正常にNoneを得た場合はOk(())を返して認証済みの任意の caller に read を許可する。これは理論上の状態ではない:
prepare_create_operations(crdt_repository.rs)が作る Create payload はaccess_policy: Noneで、owner policy は別の Update operationとして後から適用されるapply_operationsは個々の operation の失敗をログして処理を継続し、部分適用でも成功を返し得る→ 「genesis はあるが policy update が無い」レプリカが成立し、そのノードは誰にでも read を許してしまう。
暗号文の機密性は CEK が守るが、これは認可契約の代替にならない。暗号文・履歴・サイズ・更新頻度といったメタデータが漏れ、将来の暗号/鍵管理のバグを即座に平文漏洩へ拡大する。
あるべき修正
テスト観点
関連