Skip to content

Messaging Protocol ACL: close chat + skill_request authorization gap #462

@branarakic

Description

@branarakic

Context

Audit triggered by the question "who can call `invokeSkill`?" during PR #448 review. Answer today: anyone with a libp2p connection. `PROTOCOL_MESSAGE` (the transport for both `chat` and `skill_request`) authenticates the caller's peerId via Ed25519 signature but performs no authorization — there's no policy layer between "this is signed by peer X" and "X is allowed to invoke skill Y on me".

Every other DKG protocol has fit-for-purpose ACLs anchored on-chain or via the new `AgentDelegationPayload` primitive (sync, join-request, publish, verify-proposal, query-remote, etc.). `PROTOCOL_MESSAGE` is the outlier.

Plan

The canonical spec is drafted at:

📄 `dkgv10-spec/production_mainnet/05_MESSAGING_ACL_AND_HANDLER_AUDIT.md`

Key design choices (full justification in the spec):

  • Reuse `AgentDelegationPayload`, don't invent a new ACL framework. Add new scopes:
    • `chat:peer=` — explicit grant for peer-to-peer chat.
    • `skill:uri=` — explicit grant for skill invocation.
  • Same-node short-circuit: if the caller holds the daemon's auth token, bypass delegation check (preserves ElizaOS / OpenClaw adapter compat).
  • CLI surface: `dkg messaging grant --peer ... --scope chat` and `dkg messaging revoke ...`.
  • 3-phase migration:
    • Phase A (current): legacy `allowAll` default.
    • Phase B: skill default-deny — invokeSkill from unknown peers fails closed.
    • Phase C: chat default-deny — chat from unknown peers requires explicit grant.

Audit appendix (in spec)

The spec's Appendix A formally classifies every libp2p protocol handler as OK or GAP, justifies each, and flags two unrelated follow-ups:

  • `getContextGraphParticipants` TODO (sync handler).
  • `PROTOCOL_QUERY` and `PROTOCOL_DISCOVER` constants — unused; consider removing.

Acceptance criteria

  • New scopes `chat:peer=...` and `skill:uri=...` recognized by delegation verifier.
  • `MessagingPolicy` evaluated in `MessageHandler.handleIncoming` before dispatch.
  • CLI `dkg messaging grant/revoke/list` commands.
  • Phase B (`skill: deny`) shipped as default; document escape hatch.
  • Devnet test: N1 grants N2 `chat` scope, N3 has no grant — N2 chat succeeds, N3 chat fails closed.
  • Devnet test: same matrix for `skill_request`.

Background

Surfaced during the unified Messenger refactor architectural review on PR #448. Out of scope for that PR (Messenger is purely about consistent outbound delivery; this issue is about inbound authorization).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions