Skip to content

feat(relay): add channel-scoped guest invites - #3673

Open
rogersterling wants to merge 5 commits into
block:mainfrom
rogersterling:codex/channel-scoped-guest-invites
Open

feat(relay): add channel-scoped guest invites#3673
rogersterling wants to merge 5 commits into
block:mainfrom
rogersterling:codex/channel-scoped-guest-invites

Conversation

@rogersterling

Copy link
Copy Markdown

Summary

Adds identity-bound guest invite links for one active private, non-DM channel. This lets a community invite a client or support user into a specific channel without giving them normal community-wide relay access or requiring a separate community.

Guests can read and post in the granted channel and see the minimum channel/member profiles needed for that conversation. They cannot access other channels, DMs, community-wide state, search, media uploads, repositories, audio, workflows, membership administration, or other privileged surfaces.

Related issue

Closes #2475.

Security model

  • Only a relay owner/admin who is also an active owner/admin of the target channel can mint, list, or revoke guest links.
  • Each guest link is bound to one channel and one identity. Guest links are single-use.
  • Guest authorization is enforced across WebSocket REQ/COUNT/EVENT, HTTP query/count/write, profile visibility, and live fan-out.
  • Global and unscoped filters fail closed. Guests cannot use a channel tag to reach globally stored event kinds.
  • Media, Git, audio, community tools, admin commands, and DMs reject guest authority.
  • A 100-active-link cap is serialized under the channel lock; the management API still returns the complete active set.

Lifecycle and revocation

  • Making the channel public, archiving, deleting, or TTL-autoarchiving it revokes guest grants and disconnects affected sessions after commit.
  • A generation fence prevents unused links from becoming valid again after reversible lifecycle changes such as public→private or archive→unarchive.
  • Explicit channel or relay removal revokes the presented bearer and tombstones the removed identity, so unused v1/v2 invites cannot restore access.
  • Voluntary leave remains distinct from administrative removal.
  • The canonical fresh-install schema and migration 0027 contain the same guest-generation, invite-shape, grant, and tombstone structures.

Desktop

Channel owners/admins can create and copy a guest link, view every active link, and revoke links from channel management. Clipboard and revoke failures reload authoritative state; an uncertain copy attempts immediate revocation before reporting failure.

Testing

Local verification:

  • Rust format, check, and strict Clippy passed.
  • buzz-db: 95 non-Postgres unit tests passed; migration tests passed.
  • buzz-relay: 779 available tests passed.
  • buzz-admin: 2 focused role/privacy regression tests passed.
  • Desktop typecheck passed; 3,784 desktop tests passed.
  • Desktop invite API tests passed.
  • Desktop E2E build passed.
  • Playwright guest-link create/copy/list/revoke flow passed.
  • git diff --check passed.

The live Postgres guest suite could not run locally because this machine has no available Postgres/Docker runtime. CI creates a clean database from schema/schema.sql, restarts the relay with BUZZ_REQUIRE_RELAY_MEMBERSHIP=true, and runs the real guest invite E2E selection. A pre-existing Flutter test failure reproduces on clean upstream and is unrelated to this change.

Independent review

Fable 5 and GPT-5.6 Sol independently reviewed the final commit and returned GO. An earlier review found two release blockers—the incomplete canonical schema and a non-tombstoning operator removal path. Both were fixed and re-reviewed. The final privacy pass also excludes guest identities from the community-wide NIP-43 membership snapshot while preserving guest removal through the operator CLI.

Known follow-ups

  • Some guest-claim failure outcomes have structured DB logs but incomplete outcome counters.
  • An existing full member who claims a channel link can see an over-restrictive HTTP query/count result for up to the existing 10-second accessible-channel cache TTL. This does not expose data.
  • Existing public media URLs remain outside guest authorization; the desktop UI calls this out and guests cannot upload or perform authenticated media reads.

Signed-off-by: Roger Sterling <samgaddis@gmail.com>
@rogersterling
rogersterling marked this pull request as ready for review July 30, 2026 03:40
@rogersterling
rogersterling requested a review from a team as a code owner July 30, 2026 03:40
@rogersterling

Copy link
Copy Markdown
Author

@block/buzz-oss-team This is ready for maintainer review. GitHub did not auto-request the CODEOWNERS team on this fork PR, and outside contributors cannot assign the team directly, so I am flagging it here. The implementation closes #2475 with identity-bound, single-channel guest links. The PR description documents the isolation model, lifecycle revocation, test coverage, and known follow-ups. The fork Actions suites are waiting for maintainer approval.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 688dbd8c23

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/buzz-db/src/channel.rs
Comment thread crates/buzz-relay/src/api/invites.rs
Comment thread crates/buzz-db/src/channel.rs Outdated
Signed-off-by: Roger Sterling <samgaddis@gmail.com>
Signed-off-by: Roger Sterling <samgaddis@gmail.com>
@rogersterling

Copy link
Copy Markdown
Author

@codex review

@block/buzz-oss-team The review feedback is addressed and the branch is current with upstream main.

What changed:

  • Added a durable invite tombstone when an administrator removes a channel guest, while preserving voluntary leave and rejoin.
  • Forced cluster-wide reconnect after guest-to-member promotion so sessions refresh their authorization context.
  • Rechecked community archival state in the authoritative ephemeral-channel reaper update.
  • Resolved all four merge conflicts against current main.
  • Added the advisory-lock hardening found during independent review.

Verification:

  • All three new Postgres regression tests pass.
  • Rust formatting and workspace Clippy pass.
  • Buzz DB and relay unit suites pass.
  • Desktop checks, tests, and build pass.
  • Web checks and build pass.
  • Mobile format and analysis pass.
  • The full local CI command reached the mobile test suite; one unchanged channel-detail widget test failed, and this PR has no mobile diff.
  • Two independent Fable security and correctness passes returned GO at the final head, with no high, medium, or low findings.

All three review threads are resolved. Please take another look.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74f0572974

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci.yml Outdated
Comment thread crates/buzz-relay/src/handlers/side_effects.rs Outdated
Signed-off-by: Roger Sterling <samgaddis@gmail.com>
Signed-off-by: Roger Sterling <samgaddis@gmail.com>
@rogersterling
rogersterling force-pushed the codex/channel-scoped-guest-invites branch from 80ada84 to 3ec0954 Compare July 31, 2026 16:40

Copy link
Copy Markdown
Author

@codex review

Both follow-up findings are fixed at the current head (3ec09540b), all review threads are resolved, and the branch is current with upstream main. Focused Postgres leave/rejoin and administrator-removal tests pass, along with Rust formatting, relay compilation, workflow shell syntax, and diff checks. DCO is green.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 3ec09540b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

feat(relay): channel-scoped guest read/write access for public support

1 participant