Skip to content

accounts' witness client: persist the verified chain, refresh only at head, and re-offer an ambiguous append (#1067 review follow-ups) #1157

Open

Description

@antoinetoussaint-byte

Problem

The independent security review of #1067 (accounts' verified witness client) left four items open. None of them is active until a composition binds a witness, and all of them become reachable then.

  1. The verified chain lives only in memory (pkg/infra/policy_log_witness.go). policy_log_cursor stores just the sequence, and log_sequence is not unique in the table. After a restart, until the first reconcile pass:

    • a witness restored to an older state can have a narrowing committed under a sequence already recorded;
    • the first record of a page is linked to nothing;
    • a fork at the same height is not detected.

    Every record is still signed by the pinned key, so this needs a restored witness store or an equivocating key holder.

  2. A partial page refreshes reached_at (policy_log_witness.go ~318-360). With more than 500 entries unread, the host keeps serving while it drains them at 500 per pass, which contradicts the comment on Entries in business/policy_log.go.

  3. A Read response larger than the requested limit is accepted. Each record is still verified, so this is harmless today.

  4. Gaps. An append that times out or is cancelled after it actually committed becomes a gap, and this host never retries the identical entry. The gap closes the serving gate on every replica until the operation is committed.

Ask

  1. Persist the verified chain hash with the cursor, make log_sequence unique, and refuse a receipt whose sequence is at or below the reconciled cursor read before the append.
  2. Refresh reached_at only when a pass reaches the signed cursor's head, or read several pages within one pass.
  3. Refuse a page longer than the requested limit.
  4. On a timeout or cancellation after the request left, retry the identical entry until it is answered, or record the operation as pending re-offer, so a committed append is never left as a gap.

Refs #1062, #1067

Activity

  1. antoinetoussaint-byte commented on Oct 18, 2026

    @antoinetoussaint-byte
    ContributorAuthor

    Added by the round-2 review of #1067 (df82d9b):

    1. MayServe with no log wired admits without reading what the database records. A host that once ran with a witness and lost it (now refused at boot when the key is pinned, F7) could still be restarted with the pin removed. MayServe should refuse while uncommitted policy_log_commits rows exist or reconciled_sequence > 0, so a database that depends on a witness never serves without one.
    2. Probe Keys once at boot. grpc.NewClient connects lazily, so a binding to a service that is not the witness only shows up as refused narrowings and a closed serving gate. One Keys call at boot, compared with the pin, would name the mismatch; it should log the mismatch and not refuse the boot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions