Skip to content

P0: Hub Inbox Ownership & Consumer Lease #440

Description

@vansin

Summary

CommHub inbox delivery authorization is currently alias-based at the Hub boundary. A network-bound node token can supply another same-network alias to inbox read/ack/reply paths. Codex and Grok production runtimes both require the same server-owned fix.

This issue creates one shared Hub primitive. Do not duplicate this identity boundary inside either gateway.

Related: #428 (RFC-030 Codex productionization).

Security invariant

For a network-bound node token, the Hub derives an immutable consumer principal from the authenticated server context. Client-supplied alias is display-only and never authorizes claim, ack, reply, or dead-letter.

The first acceptance test is the existing real-entry negative case:

A node token bound to node A supplies node B's same-network alias to get_inbox, ack_inbox, reply, or dead-letter. Every operation must fail closed and leave node B's rows/tasks unchanged.

The test must fail on the current baseline before the fix.

Two distinct leases — never combine them

  1. Hub delivery consumer lease: who may claim/ack/reply one Hub inbox delivery. Implemented in server/src; shared by Codex and Grok.
  2. Gateway local reservation / TUI owner lease: who owns a local runtime turn. Implemented inside each gateway.

These are different tokens, lifecycles and trust boundaries. One must never be accepted in place of the other.

Required Hub design

Authenticated consumer principal

  • Resolve from the authenticated token record and effective network, never from a token prefix, alias, body, metadata or query parameter.
  • Use stable server identity (node id + network binding); record token id for authentication/audit, not as the sole long-lived node identity.
  • A network token used outside its bound network resolves to no consumer principal.
  • Human/admin inspection is a separate explicit privileged API. It must not reuse the node self-inbox path with a caller-selected alias.

Atomic database primitive

Implement one shared adapter-level operation for self-inbox claim. Handler code must not reimplement the authorization SQL.

The primitive atomically:

  • selects only rows addressed to the server-resolved consumer principal/network;
  • writes a server-minted lease id, monotonic epoch/version, claim time and expiry;
  • returns the claimed rows plus lease metadata;
  • makes concurrent claimers mutually exclusive.

Ack, reply and dead-letter must run through shared adapter primitives and atomically verify:

  • message id and canonical task id;
  • consumer principal;
  • network;
  • active, unexpired lease id and epoch.

Retry, reassign and cancel invalidate all older delivery leases/epochs. Late acknowledgements from an older delivery must not mutate the current attempt.

Surfaces

  • MCP, REST and SSE/push-related consumers use the same server primitives.
  • SQLite and PostgreSQL adapters have identical semantics and conformance tests.
  • If PgAdapter cannot guarantee the transaction/lease semantics, PostgreSQL fails closed for these operations. Do not emulate the transaction with separate per-statement connections.
  • Legacy method names may remain for compatibility, but the node-token path must ignore/reject a mismatched alias and require the server-issued lease. A versioned claim_self_inbox / ack_claimed_inbox API is acceptable if that makes compatibility explicit.

Required tests

Real auth-entry negatives

  • same-network node A token + node B alias: cannot read, claim, ack, reply or dead-letter B;
  • cross-network node token: cannot act;
  • forged from_session / display alias has no effect;
  • expired/stale/wrong lease and wrong epoch cannot mutate;
  • retry/reassign/cancel invalidate the prior lease;
  • concurrent claim: exactly one active consumer lease;
  • mismatched canonical task claim cannot affect a healthy task.

Positive/backward compatibility

  • node token claims and completes its own row;
  • token rotation for the same stable node identity follows the explicit lease policy;
  • authorized human/admin inspection works only through the privileged path;
  • ordinary sender-principal stamping remains unchanged;
  • Codex and Grok thin adapters each pass one integration test without implementing their own auth SQL.

Adapter matrix

Run the same contract suite against SQLite and PostgreSQL. Any adapter without real atomicity is rejected at preflight.

Delivery rules

  • Clean worktree and isolated DB.
  • Additive migration with an explicit compatibility/rollback analysis.
  • Author does not self-review or merge.
  • No production deployment or latest switch from this issue.
  • Independent security review is required before merge because this changes a live authorization boundary.

Out of scope

  • Gateway local human-vs-agent reservation.
  • Codex/Grok scheduler policy.
  • Production deployment or runtime promotion.

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