Skip to content

security: authenticate and bind Murmur ACKs - #104

Draft
fedoseevstanislav wants to merge 1 commit into
alexfrmn:mainfrom
fedoseevstanislav:security/728-signed-acks
Draft

security: authenticate and bind Murmur ACKs#104
fedoseevstanislav wants to merge 1 commit into
alexfrmn:mainfrom
fedoseevstanislav:security/728-signed-acks

Conversation

@fedoseevstanislav

Copy link
Copy Markdown

What changed

  • replace legacy {msgId,status} delivery ACKs with a versioned Ed25519-signed AckV1 envelope;
  • bind every ACK/NACK to the exact message digest, conversation, original sender, intended recipient, consumer, timestamp, and unique ACK nonce;
  • make NATS and WebSocket correlation fail closed on unsigned, stale, wrongly signed, wrongly bound, replayed, unknown, or wrong-subject ACKs;
  • persist processed ACK nonces and apply verified outbox transitions exactly once, including across retries and restarts;
  • prevent a fast ACK from being overwritten by the sender's subsequent markSent call;
  • remove the A2A bridge's unauthenticated raw-NACK task-resolution shortcut;
  • wire ACK signing and pinned-peer verification into the daemon, MCP channel server, runner, and demos;
  • add rejection counters and metadata-only logging; and
  • document the coordinated, wire-breaking rollout and rollback procedure.

Why

ACK correlation previously trusted attacker-controlled JSON containing only a message id and status. Anyone able to publish to an ACK subject could mark an arbitrary pending outbox row acked or failed, suppressing delivery or forcing retries without authenticating the purported consumer.

This change makes the security invariant explicit: only a fresh ACK signed by a pinned intended peer and bound to the exact pending envelope may transition that outbox row, and each signed ACK is processed at most once.

Related estate finding: fedoseevstanislav/ops#728.

Impact and rollout

This is intentionally wire-breaking: legacy peers cannot produce the new ACK shape, and upgraded peers reject legacy ACKs. Do not deploy this PR to a mixed-version mesh. Follow docs/signed-acks.md and upgrade all Murmur peers in one maintenance window.

The separate NATS TLS/per-peer ACL work in #103 remains complementary: ACLs reduce who can reach ACK subjects; this PR makes forged ACK content ineffective even after subject access.

No live deployment is included in this PR.

Validation

  • npm test — passed (root unit, core, notification, ACP/send boundaries, A2A, WebSocket, federation, and federation-NATS suites)
  • npm audit --audit-level=moderate — 0 vulnerabilities
  • dedicated regression tests cover unsigned ACK rejection, real Ed25519 verification, peer/conversation/digest/recipient binding, freshness, replay, durable restart behavior, per-agent subjects, metadata-only rejection logs, NACK retry behavior, and the A2A raw-NACK sink
  • npm run test:integration — skipped by the repository runner because Docker is unavailable on the test Mac; coordinated real-mesh smoke testing remains a deployment gate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant