Skip to content

[WIP] Improve group feature of Skychat, both on features and infrastructures - #3631

Merged
0pcom merged 18 commits into
skycoin:developfrom
mrpalide:feat/improve-group-chat-features
Jul 31, 2026
Merged

[WIP] Improve group feature of Skychat, both on features and infrastructures #3631
0pcom merged 18 commits into
skycoin:developfrom
mrpalide:feat/improve-group-chat-features

Conversation

@mrpalide

@mrpalide mrpalide commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Did you run make format && make check? Yes

Fixes: Part of #3559

Changes:

  • add group admission control — join requests, approval queue, kick/ban/mute/read-only
  • reject stale roster/admin/mod gossip — replaying an old signed leaf silently undid evictions
  • let an invite name several admins — join requests pointed at OwnerPK alone, so an offline founder meant nobody could join
  • promote/demote from the members panel — the RPC existed, nothing called it, so a group could never get a second admin
  • rotate the group key on eviction — a ban took the seat but left the key, so a copy of the feed kept opening
  • seal group keys at rest — groups.db handed over every private group's AES key to anyone who could read the file
  • serve group history from any online member, not just admins — admin-toggleable per group, choosable at create time
  • price and rate-limit joining — free public keys meant a flood could outrun any per-PK gate, including ban
  • bound compromise in time — DH-ratcheted epoch keys for DMs, ephemeral wraps and age/volume rotation for groups
  • fix CI — realistic per-package test timeout, and move DmsgVisorRPCPort off a port the visor already binds
  • encrypt governance gossip — roster/admin/mod leaves are signed but plaintext, so who you banned and muted is readable even in an encrypted group
  • encrypt group file bytes — messages are sealed, attachments aren't; files ride the backfill path with no group-key encryption
  • "ask again" after a declined request — denial is terminal by design, so the UI needs an explicit retry button
  • [ ] retention / disappearing messages — no TTL, no expiry; data accumulates forever and delete-for-everyone is cooperative
  • [ ] metadata reduction — SenderPK and exact timestamps sit in the clear beside the ciphertext, and the federated topology exposes the subscription graph

How to test this PR:

Browser, against three real visors:

make e2e-build && make e2e-run && make e2e-skychat

then, across the three UIs it prints:

  1. Create a private group on visor A. Invite link alone should NOT let B in —
    B lands in A's approval queue; approve it and B gets the key with the
    approval, not from the link.
  2. Create a public group. The link alone should be enough, and the first join
    should visibly cost a moment (proof-of-work) rather than being instant.
  3. Ban B from the private group. B loses the seat AND stops being able to read
    new messages; A's admin panel shows the key epoch advance. Older messages
    stay readable for everyone still in.
  4. Promote C to admin, take A offline, then have a fourth visor join using the
    same invite link — C should be able to admit it.
  5. Open a DM between two paired visors and send one message each way. The chat
    header should move from "encrypted · keys not exchanged yet" to
    "forward secret · key " once both sides have spoken.

mrpalide added 17 commits July 29, 2026 22:26
…alone, so an offline founder meant nobody could join
… second admin, and a stale read-modify-Put dropped replay

  watermarks
…toggleable per group and choosable at create time
…move DmsgVisorRPCPort off a port the visor already

  binds
@mrpalide mrpalide changed the title Improve group feature of Skychat, both on features and infrastructures [WIP] Improve group feature of Skychat, both on features and infrastructures Jul 31, 2026
… it out from under membersMu, and -race found seven
0pcom added a commit to 0pcom/skywire that referenced this pull request Jul 31, 2026
…n item from the admission-control work

Completes the one unchecked box in the group-admission feature set: a
declined requester can DELIBERATELY re-request, without letting a refused key
spam the approval queue by polling.

A passive re-ask from a denied PK stays terminal (that is what defeats the
poll-flood). "Ask again" is the explicit retry: it replaces the denied record
with a fresh pending one after paying the SAME proof-of-work and rate-limit
gates as a first request, so a declined key can queue no faster than a new
one. Against an admin on an older build the flag is ignored and the denial is
surfaced honestly.

Core (pkg/skychat/group):
- JoinRequestMsg.AskAgain wire flag, carried on BOTH the single-admin fast
  path and the multi-admin fan-out (the two send sites);
- Manager.AskAgain(id) derives everything from the stored record (no invite
  re-paste) + a shared applyJoinResponse used by the retry loop too;
- the admission handler honors AskAgain only past every cost gate.

Surfaces (parity across all four):
- Visor.GroupAskAgain + RPC (iface/server/client/mock; proxied via embedding);
- native app HTTP POST /group/<id>/ask-again;
- wasm skychatGroupAskAgain hook;
- CLI `skywire cli skychat group ask-again <id>`;
- HV UI: pending/declined room badges + inline "ask again" button + i18n.

Tests: TestAdmission_AskAgainRequeuesAfterDecline + the passive-terminal test
pass; full pkg/skychat/group green (ok, 77.6% coverage) over the
pkg/skychat/group relocation.

Remaining skycoin#3631 items (retention/TTL, metadata reduction) are deferred to the
message-persistence + anti-abuse design track.
@0pcom
0pcom merged commit a6c26d4 into skycoin:develop Jul 31, 2026
22 of 24 checks passed
0pcom added a commit that referenced this pull request Jul 31, 2026
feat(skychat): group admission control + encryption hardening (continues #3631) + "ask again"
@0pcom

0pcom commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Landed on develop — thank you for all of this work. 🙏

Your PR conflicted only because of the cmd/apps/skychat/grouppkg/skychat/group relocation, so I replicated your branch over the move and merged it via #3644, with all your commits preserved under your authorship. Everything in the checked list shipped: admission control, stale-gossip rejection, multi-admin invites, promote/demote, key rotation on eviction, sealed keys at rest, member-served history, PoW + join rate-limiting, epoch-key ratcheting, encrypted governance gossip + attachments, and the CI test-timeout fix (I also extended that to the darwin lane, which was still on the inline 5m).

I finished the one remaining checked-but-open item — "ask again" after a decline — end to end (core + RPC + native app HTTP + wasm hook + CLI + HV UI badge/button), so a declined requester can deliberately re-queue while a passive re-ask stays terminal (no poll-flood).

The two still-unchecked items — retention/TTL (disappearing messages) and metadata reduction — I deferred rather than block the merge; they fold into a message-persistence + anti-abuse design pass we're planning (bounded store + disk-fill protection). Happy to collaborate on those. This PR can be closed as landed.

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.

2 participants